@textbus/platform-browser 5.2.2 → 5.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,872 @@
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=`
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const core$1 = require("@textbus/core");
4
+ const stream = require("@tanbo/stream");
5
+ const core = require("@viewfly/core");
6
+ function createElement(tagName, options = {}) {
7
+ const el = document.createElement(tagName);
8
+ if (options.classes) {
9
+ el.classList.add(...options.classes);
10
+ }
11
+ if (options.attrs) {
12
+ Object.keys(options.attrs).forEach((key) => {
13
+ el.setAttribute(key, options.attrs[key]);
14
+ });
15
+ }
16
+ if (options.props) {
17
+ Object.keys(options.props).forEach((key) => {
18
+ el[key] = options.props[key];
19
+ });
20
+ }
21
+ if (options.styles) {
22
+ Object.assign(el.style, options.styles);
23
+ }
24
+ if (options.children) {
25
+ options.children.filter((i) => i).forEach((item) => {
26
+ el.appendChild(item);
27
+ });
28
+ }
29
+ if (options.on) {
30
+ Object.keys(options.on).forEach((key) => {
31
+ el.addEventListener(key, options.on[key]);
32
+ });
33
+ }
34
+ return el;
35
+ }
36
+ function getLayoutRectByRange(range) {
37
+ let { startContainer, startOffset } = range;
38
+ if (startContainer.nodeType === Node.TEXT_NODE) {
39
+ if (startOffset > 0) {
40
+ return range.getBoundingClientRect();
41
+ }
42
+ const parentNode = startContainer.parentNode;
43
+ startOffset = Array.from(parentNode.childNodes).indexOf(startContainer);
44
+ startContainer = parentNode;
45
+ }
46
+ const beforeNode = startContainer.childNodes[startOffset - 1];
47
+ if (beforeNode) {
48
+ if (beforeNode.nodeType === Node.ELEMENT_NODE && beforeNode.nodeName.toLowerCase() !== "br") {
49
+ const rect2 = beforeNode.getBoundingClientRect();
50
+ return {
51
+ left: rect2.right,
52
+ top: rect2.top,
53
+ width: range.collapsed ? 1 : rect2.width,
54
+ height: rect2.height
55
+ };
56
+ } else if (beforeNode.nodeType === Node.TEXT_NODE) {
57
+ const range2 = document.createRange();
58
+ range2.setStart(beforeNode, beforeNode.textContent.length);
59
+ range2.setEnd(beforeNode, beforeNode.textContent.length);
60
+ const rect2 = range2.getBoundingClientRect();
61
+ return {
62
+ left: rect2.right,
63
+ top: rect2.top,
64
+ width: range.collapsed ? 1 : rect2.width,
65
+ height: rect2.height
66
+ };
67
+ }
68
+ }
69
+ const offsetNode = startContainer.childNodes[startOffset];
70
+ let isInsertBefore = false;
71
+ if (!offsetNode) {
72
+ const lastChild = startContainer.lastChild;
73
+ if (lastChild && lastChild.nodeType === Node.ELEMENT_NODE) {
74
+ const rect2 = lastChild.getBoundingClientRect();
75
+ return {
76
+ left: rect2.right,
77
+ top: rect2.top,
78
+ width: range.collapsed ? 1 : rect2.width,
79
+ height: rect2.height
80
+ };
81
+ }
82
+ }
83
+ if (offsetNode) {
84
+ if (offsetNode.nodeType === Node.ELEMENT_NODE && offsetNode.nodeName.toLowerCase() !== "br") {
85
+ const rect2 = offsetNode.getBoundingClientRect();
86
+ return {
87
+ left: rect2.left,
88
+ top: rect2.top,
89
+ width: range.collapsed ? 1 : rect2.width,
90
+ height: rect2.height
91
+ };
92
+ }
93
+ isInsertBefore = true;
94
+ }
95
+ const span = startContainer.ownerDocument.createElement("span");
96
+ span.innerText = "​";
97
+ span.style.display = "inline-block";
98
+ if (isInsertBefore) {
99
+ startContainer.insertBefore(span, offsetNode);
100
+ } else {
101
+ startContainer.appendChild(span);
102
+ }
103
+ const rect = span.getBoundingClientRect();
104
+ startContainer.removeChild(span);
105
+ return {
106
+ left: rect.left,
107
+ top: rect.top,
108
+ width: range.collapsed ? 1 : rect.width,
109
+ height: rect.height
110
+ };
111
+ }
112
+ const isWindows = () => /win(dows|32|64)/i.test(navigator.userAgent);
113
+ const isMac = () => /mac os/i.test(navigator.userAgent);
114
+ const isSafari = () => /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
115
+ const isFirefox = () => /Firefox/.test(navigator.userAgent);
116
+ const isMobileBrowser = () => /Android|iPhone|iPad/.test(navigator.userAgent);
117
+ const EDITOR_OPTIONS = new core.InjectionToken("EDITOR_OPTIONS");
118
+ const VIEW_CONTAINER = new core.InjectionToken("VIEW_CONTAINER");
119
+ const VIEW_DOCUMENT = new core.InjectionToken("VIEW_DOCUMENT");
120
+ const VIEW_MASK = new core.InjectionToken("VIEW_MASK");
121
+ var __getOwnPropDesc$4 = Object.getOwnPropertyDescriptor;
122
+ var __decorateClass$4 = (decorators, target, key, kind) => {
123
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$4(target, key) : target;
124
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
125
+ if (decorator = decorators[i])
126
+ result = decorator(result) || result;
127
+ return result;
128
+ };
129
+ var __decorateParam$2 = (index, decorator) => (target, key) => decorator(target, key, index);
130
+ exports.Parser = class Parser {
131
+ constructor(options, textbus) {
132
+ this.textbus = textbus;
133
+ const componentLoaders = [
134
+ ...options.componentLoaders || []
135
+ ];
136
+ const formatLoaders = [
137
+ ...options.formatLoaders || []
138
+ ];
139
+ const attributeLoaders = [
140
+ ...options.attributeLoaders || []
141
+ ];
142
+ this.componentLoaders = componentLoaders;
143
+ this.formatLoaders = formatLoaders;
144
+ this.attributeLoaders = attributeLoaders;
145
+ }
146
+ textbus;
147
+ static parseHTML(html) {
148
+ return new DOMParser().parseFromString(html, "text/html").body;
149
+ }
150
+ componentLoaders;
151
+ formatLoaders;
152
+ attributeLoaders;
153
+ /**
154
+ * 使用指定的组件加载器解析一段 HTML 字符串或 DOM 元素
155
+ * @param html
156
+ * @param rootComponentLoader
157
+ */
158
+ parseDoc(html, rootComponentLoader) {
159
+ const element = typeof html === "string" ? exports.Parser.parseHTML(html) : html;
160
+ return rootComponentLoader.read(
161
+ element,
162
+ this.textbus,
163
+ (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {
164
+ return this.readSlot(childSlot, slotRootElement, slotContentHostElement);
165
+ }
166
+ );
167
+ }
168
+ /**
169
+ * 将一段 HTML 或 DOM 元素解析到指定插槽
170
+ * @param html
171
+ * @param rootSlot
172
+ */
173
+ parse(html, rootSlot) {
174
+ const element = typeof html === "string" ? exports.Parser.parseHTML(html) : html;
175
+ return this.readFormats(element, rootSlot);
176
+ }
177
+ readComponent(el, slot) {
178
+ if (el.nodeType === Node.ELEMENT_NODE) {
179
+ if (el.tagName === "BR") {
180
+ slot.insert("\n");
181
+ return;
182
+ }
183
+ const schema = [...slot.schema];
184
+ for (const t of this.componentLoaders) {
185
+ if (t.match(el, schema)) {
186
+ const result = t.read(
187
+ el,
188
+ this.textbus,
189
+ (childSlot, slotRootElement, slotContentHostElement = slotRootElement) => {
190
+ return this.readSlot(childSlot, slotRootElement, slotContentHostElement);
191
+ }
192
+ );
193
+ if (!result) {
194
+ return;
195
+ }
196
+ if (result instanceof core$1.Slot) {
197
+ result.toDelta().forEach((i) => slot.insert(i.insert, i.formats));
198
+ return;
199
+ }
200
+ slot.insert(result);
201
+ return;
202
+ }
203
+ }
204
+ this.readFormats(el, slot);
205
+ } else if (el.nodeType === Node.TEXT_NODE) {
206
+ this.readText(slot, el);
207
+ }
208
+ }
209
+ readText(slot, el) {
210
+ const textContent = el.textContent;
211
+ if (/^\s*[\r\n\u200b]+\s*$/.test(textContent)) {
212
+ return;
213
+ }
214
+ slot.insert(textContent);
215
+ }
216
+ readFormats(el, slot) {
217
+ const formats = this.formatLoaders.filter((f) => {
218
+ return f.match(el);
219
+ }).map((f) => {
220
+ return f.read(el);
221
+ });
222
+ const startIndex = slot.index;
223
+ let startNode = el.firstChild;
224
+ while (startNode) {
225
+ this.readComponent(startNode, slot);
226
+ startNode = startNode.nextSibling;
227
+ }
228
+ const endIndex = slot.index;
229
+ this.applyFormats(slot, formats.map((i) => {
230
+ return {
231
+ formatter: i.formatter,
232
+ value: i.value,
233
+ startIndex,
234
+ endIndex
235
+ };
236
+ }));
237
+ slot.retain(endIndex);
238
+ return slot;
239
+ }
240
+ readSlot(childSlot, slotRootElement, slotContentElement) {
241
+ if (slotRootElement.nodeType === Node.ELEMENT_NODE) {
242
+ this.attributeLoaders.filter((a) => {
243
+ return a.match(slotRootElement);
244
+ }).forEach((a) => {
245
+ const r = a.read(slotRootElement);
246
+ childSlot.setAttribute(r.attribute, r.value);
247
+ });
248
+ }
249
+ if (slotContentElement.nodeType === Node.ELEMENT_NODE) {
250
+ this.readFormats(slotContentElement, childSlot);
251
+ } else {
252
+ this.readText(childSlot, slotContentElement);
253
+ }
254
+ return childSlot;
255
+ }
256
+ applyFormats(slot, formatItems) {
257
+ slot.background(() => {
258
+ formatItems.forEach((i) => {
259
+ slot.retain(i.startIndex);
260
+ slot.retain(i.endIndex - i.startIndex, i.formatter, i.value);
261
+ });
262
+ });
263
+ }
264
+ };
265
+ exports.Parser = __decorateClass$4([
266
+ core.Injectable(),
267
+ __decorateParam$2(0, core.Inject(EDITOR_OPTIONS))
268
+ ], exports.Parser);
269
+ var __getOwnPropDesc$3 = Object.getOwnPropertyDescriptor;
270
+ var __decorateClass$3 = (decorators, target, key, kind) => {
271
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$3(target, key) : target;
272
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
273
+ if (decorator = decorators[i])
274
+ result = decorator(result) || result;
275
+ return result;
276
+ };
277
+ var __decorateParam$1 = (index, decorator) => (target, key) => decorator(target, key, index);
278
+ exports.SelectionBridge = class SelectionBridge {
279
+ constructor(config, textbus, controller, selection, rootComponentRef, input, scheduler, domAdapter) {
280
+ this.config = config;
281
+ this.selection = selection;
282
+ this.rootComponentRef = rootComponentRef;
283
+ this.input = input;
284
+ this.scheduler = scheduler;
285
+ this.domAdapter = domAdapter;
286
+ this.docContainer = textbus.get(VIEW_DOCUMENT);
287
+ this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(stream.filter(() => {
288
+ return !controller.readonly;
289
+ }));
290
+ this.sub = this.onSelectionChange.subscribe((r) => {
291
+ if (r) {
292
+ input.focus(r, this.changeFromUser);
293
+ } else {
294
+ input.blur();
295
+ }
296
+ });
297
+ this.sub.add(
298
+ stream.fromEvent(document, "focusin").subscribe((ev) => {
299
+ let target = ev.target;
300
+ if (/^(input|textarea|select)$/i.test(target.nodeName)) {
301
+ if (target.tagName.toLowerCase() === "input" && /^(range|date)$/.test(target.type)) {
302
+ return;
303
+ }
304
+ this.ignoreSelectionChange = true;
305
+ return;
306
+ }
307
+ if (!config.useContentEditable) {
308
+ while (target) {
309
+ if (target.contentEditable === "true") {
310
+ this.ignoreSelectionChange = true;
311
+ return;
312
+ }
313
+ target = target.parentNode;
314
+ }
315
+ }
316
+ })
317
+ );
318
+ this.sub.add(
319
+ stream.fromEvent(document, "focusout").subscribe(() => {
320
+ this.ignoreSelectionChange = false;
321
+ })
322
+ );
323
+ }
324
+ config;
325
+ selection;
326
+ rootComponentRef;
327
+ input;
328
+ scheduler;
329
+ domAdapter;
330
+ onSelectionChange;
331
+ nativeSelection = document.getSelection();
332
+ syncSelectionFromNativeSelectionChange = true;
333
+ selectionChangeEvent = new stream.Subject();
334
+ subs = [];
335
+ sub;
336
+ connector = null;
337
+ ignoreSelectionChange = false;
338
+ changeFromUser = false;
339
+ docContainer;
340
+ cacheCaretPositionTimer;
341
+ oldCaretPosition;
342
+ connect(connector) {
343
+ this.disConnect();
344
+ this.connector = connector;
345
+ this.syncSelection(connector);
346
+ this.listen(connector);
347
+ }
348
+ disConnect() {
349
+ this.connector = null;
350
+ this.unListen();
351
+ }
352
+ getRect(location) {
353
+ const { focus, anchor } = this.getPositionByRange({
354
+ focusOffset: location.offset,
355
+ anchorOffset: location.offset,
356
+ focusSlot: location.slot,
357
+ anchorSlot: location.slot
358
+ });
359
+ if (!focus || !anchor) {
360
+ return null;
361
+ }
362
+ const nativeRange = document.createRange();
363
+ nativeRange.setStart(focus.node, focus.offset);
364
+ nativeRange.collapse();
365
+ return getLayoutRectByRange(nativeRange);
366
+ }
367
+ restore(abstractSelection, fromLocal) {
368
+ this.changeFromUser = fromLocal;
369
+ if (this.ignoreSelectionChange || !this.connector) {
370
+ return;
371
+ }
372
+ this.unListen();
373
+ if (!abstractSelection) {
374
+ this.nativeSelection.removeAllRanges();
375
+ this.selectionChangeEvent.next(null);
376
+ this.listen(this.connector);
377
+ return;
378
+ }
379
+ const { focus, anchor } = this.getPositionByRange(abstractSelection);
380
+ if (!focus || !anchor) {
381
+ this.nativeSelection.removeAllRanges();
382
+ this.selectionChangeEvent.next(null);
383
+ this.listen(this.connector);
384
+ return;
385
+ }
386
+ function tryOffset(position) {
387
+ if (!position.node) {
388
+ return;
389
+ }
390
+ if (position.node.nodeType === Node.TEXT_NODE) {
391
+ const len = position.node.textContent.length;
392
+ if (position.offset > len) {
393
+ position.offset = len;
394
+ }
395
+ } else if (position.node.nodeType === Node.ELEMENT_NODE) {
396
+ const len = position.node.childNodes.length;
397
+ if (position.offset > len) {
398
+ position.offset = len;
399
+ }
400
+ }
401
+ }
402
+ try {
403
+ tryOffset(focus);
404
+ tryOffset(anchor);
405
+ this.nativeSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
406
+ } catch (e) {
407
+ setTimeout(() => {
408
+ throw e;
409
+ });
410
+ }
411
+ if (this.nativeSelection.rangeCount) {
412
+ const nativeRange = this.nativeSelection.getRangeAt(0);
413
+ this.selectionChangeEvent.next(nativeRange);
414
+ } else {
415
+ this.selectionChangeEvent.next(null);
416
+ }
417
+ const bind = () => {
418
+ if (this.connector) {
419
+ this.listen(this.connector);
420
+ }
421
+ };
422
+ if (fromLocal) {
423
+ Promise.resolve().then(bind);
424
+ return;
425
+ }
426
+ if (typeof requestIdleCallback === "function") {
427
+ requestIdleCallback(bind);
428
+ } else {
429
+ setTimeout(bind, 30);
430
+ }
431
+ }
432
+ destroy() {
433
+ this.subs.forEach((i) => i.unsubscribe());
434
+ this.sub.unsubscribe();
435
+ }
436
+ getPositionByRange(abstractSelection) {
437
+ let focus;
438
+ let anchor;
439
+ try {
440
+ focus = this.findSelectedNodeAndOffset(abstractSelection.focusSlot, abstractSelection.focusOffset);
441
+ anchor = focus;
442
+ if (abstractSelection.anchorSlot !== abstractSelection.focusSlot || abstractSelection.anchorOffset !== abstractSelection.focusOffset) {
443
+ anchor = this.findSelectedNodeAndOffset(abstractSelection.anchorSlot, abstractSelection.anchorOffset);
444
+ }
445
+ return {
446
+ focus,
447
+ anchor
448
+ };
449
+ } catch (e) {
450
+ return {
451
+ focus: null,
452
+ anchor: null
453
+ };
454
+ }
455
+ }
456
+ getPreviousLinePositionByCurrent(position) {
457
+ return this.getLinePosition(position, false);
458
+ }
459
+ getNextLinePositionByCurrent(position) {
460
+ return this.getLinePosition(position, true);
461
+ }
462
+ getLinePosition(currentPosition, toNext) {
463
+ clearTimeout(this.cacheCaretPositionTimer);
464
+ let p;
465
+ if (this.oldCaretPosition) {
466
+ p = toNext ? this.getNextLinePositionByOffset(currentPosition, this.oldCaretPosition.left) : this.getPreviousLinePositionByOffset(currentPosition, this.oldCaretPosition.left);
467
+ } else {
468
+ this.oldCaretPosition = this.getRect(currentPosition);
469
+ p = toNext ? this.getNextLinePositionByOffset(currentPosition, this.oldCaretPosition.left) : this.getPreviousLinePositionByOffset(currentPosition, this.oldCaretPosition.left);
470
+ }
471
+ this.cacheCaretPositionTimer = setTimeout(() => {
472
+ this.oldCaretPosition = null;
473
+ }, 3e3);
474
+ return p;
475
+ }
476
+ /**
477
+ * 获取选区向上移动一行的位置。
478
+ * @param currentPosition
479
+ * @param startLeft 参考位置。
480
+ */
481
+ getPreviousLinePositionByOffset(currentPosition, startLeft) {
482
+ let isToPrevLine = false;
483
+ let loopCount = 0;
484
+ let minLeft = startLeft;
485
+ let focusSlot = currentPosition.slot;
486
+ let focusOffset = currentPosition.offset;
487
+ let minTop = this.getRect({
488
+ slot: focusSlot,
489
+ offset: focusOffset
490
+ }).top;
491
+ let position;
492
+ let oldPosition;
493
+ let oldLeft = 0;
494
+ while (true) {
495
+ loopCount++;
496
+ position = this.selection.getPreviousPositionByPosition(focusSlot, focusOffset);
497
+ focusSlot = position.slot;
498
+ focusOffset = position.offset;
499
+ const rect2 = this.getRect(position);
500
+ if (!isToPrevLine) {
501
+ if (rect2.left > minLeft || rect2.top + rect2.height <= minTop) {
502
+ isToPrevLine = true;
503
+ } else if (rect2.left === minLeft && rect2.top === minTop) {
504
+ return position;
505
+ }
506
+ minLeft = rect2.left;
507
+ minTop = rect2.top;
508
+ }
509
+ if (isToPrevLine) {
510
+ if (rect2.left <= startLeft) {
511
+ return position;
512
+ }
513
+ if (oldPosition) {
514
+ if (rect2.left >= oldLeft) {
515
+ return oldPosition;
516
+ }
517
+ }
518
+ oldLeft = rect2.left;
519
+ oldPosition = position;
520
+ }
521
+ if (loopCount > 1e4) {
522
+ break;
523
+ }
524
+ }
525
+ return position || {
526
+ offset: 0,
527
+ slot: focusSlot
528
+ };
529
+ }
530
+ /**
531
+ * 获取选区向下移动一行的位置。
532
+ * @param currentPosition
533
+ * @param startLeft 参考位置。
534
+ */
535
+ getNextLinePositionByOffset(currentPosition, startLeft) {
536
+ let isToNextLine = false;
537
+ let loopCount = 0;
538
+ let maxRight = startLeft;
539
+ let focusSlot = currentPosition.slot;
540
+ let focusOffset = currentPosition.offset;
541
+ const rect = this.getRect({
542
+ slot: focusSlot,
543
+ offset: focusOffset
544
+ });
545
+ let minTop = rect.top;
546
+ let oldPosition;
547
+ let oldLeft = 0;
548
+ while (true) {
549
+ loopCount++;
550
+ const position = this.selection.getNextPositionByPosition(focusSlot, focusOffset);
551
+ focusSlot = position.slot;
552
+ focusOffset = position.offset;
553
+ const rect2 = this.getRect(position);
554
+ if (!isToNextLine) {
555
+ if (rect2.left < maxRight || rect2.top >= minTop + rect.height) {
556
+ isToNextLine = true;
557
+ } else if (rect2.left === maxRight && rect2.top === minTop) {
558
+ return position;
559
+ }
560
+ maxRight = rect2.left;
561
+ minTop = rect2.top;
562
+ oldPosition = position;
563
+ }
564
+ if (isToNextLine) {
565
+ if (rect2.left > startLeft) {
566
+ return oldPosition;
567
+ }
568
+ if (oldPosition) {
569
+ if (rect2.left <= oldLeft) {
570
+ return oldPosition;
571
+ }
572
+ }
573
+ oldPosition = position;
574
+ oldLeft = rect2.left;
575
+ }
576
+ if (loopCount > 1e4) {
577
+ break;
578
+ }
579
+ }
580
+ return oldPosition || {
581
+ offset: focusSlot.length,
582
+ slot: focusSlot
583
+ };
584
+ }
585
+ unListen() {
586
+ this.subs.forEach((i) => i.unsubscribe());
587
+ this.subs = [];
588
+ }
589
+ listen(connector) {
590
+ if (!this.config.useContentEditable) {
591
+ const selection = this.nativeSelection;
592
+ this.subs.push(
593
+ stream.fromEvent(this.docContainer, "mousedown").subscribe((ev) => {
594
+ if (this.ignoreSelectionChange || ev.button === 2) {
595
+ return;
596
+ }
597
+ if (!ev.shiftKey) {
598
+ selection.removeAllRanges();
599
+ }
600
+ })
601
+ );
602
+ }
603
+ let isUpdating = false;
604
+ this.subs.push(
605
+ this.scheduler.onDocChange.subscribe(() => {
606
+ isUpdating = true;
607
+ }),
608
+ this.scheduler.onDocChanged.pipe(stream.delay()).subscribe(() => {
609
+ isUpdating = false;
610
+ }),
611
+ stream.fromEvent(document, "selectionchange").subscribe(() => {
612
+ if (isUpdating) {
613
+ return;
614
+ }
615
+ if (this.syncSelectionFromNativeSelectionChange) {
616
+ this.syncSelection(connector);
617
+ }
618
+ })
619
+ );
620
+ }
621
+ syncSelection(connector) {
622
+ const selection = this.nativeSelection;
623
+ this.changeFromUser = true;
624
+ if (this.ignoreSelectionChange || this.input.composition || selection.rangeCount === 0 || !this.docContainer.contains(selection.anchorNode) || this.rootComponentRef.component.slots.length === 0) {
625
+ return;
626
+ }
627
+ const rawRange = selection.getRangeAt(0);
628
+ const nativeRange = rawRange.cloneRange();
629
+ const isFocusEnd = selection.focusNode === nativeRange.endContainer && selection.focusOffset === nativeRange.endOffset;
630
+ const isFocusStart = selection.focusNode === nativeRange.startContainer && selection.focusOffset === nativeRange.startOffset;
631
+ if (!this.docContainer.contains(selection.focusNode)) {
632
+ if (isFocusEnd) {
633
+ const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(0));
634
+ if (!nativeNode) {
635
+ return;
636
+ }
637
+ nativeRange.setEndAfter(nativeNode.lastChild);
638
+ } else {
639
+ const nativeNode = this.domAdapter.getNativeNodeBySlot(this.rootComponentRef.component.slots.at(-1));
640
+ if (!nativeNode) {
641
+ return;
642
+ }
643
+ nativeRange.setStartBefore(nativeNode.firstChild);
644
+ }
645
+ }
646
+ const startPosition = this.getCorrectedPosition(nativeRange.startContainer, nativeRange.startOffset, isFocusStart);
647
+ const endPosition = nativeRange.collapsed ? startPosition : this.getCorrectedPosition(nativeRange.endContainer, nativeRange.endOffset, isFocusEnd);
648
+ if ([Node.ELEMENT_NODE, Node.TEXT_NODE].includes(nativeRange.commonAncestorContainer?.nodeType) && startPosition && endPosition) {
649
+ const abstractSelection = connector.beforeChange(isFocusEnd ? {
650
+ anchorSlot: startPosition.slot,
651
+ anchorOffset: startPosition.offset,
652
+ focusSlot: endPosition.slot,
653
+ focusOffset: endPosition.offset
654
+ } : {
655
+ focusSlot: startPosition.slot,
656
+ focusOffset: startPosition.offset,
657
+ anchorSlot: endPosition.slot,
658
+ anchorOffset: endPosition.offset
659
+ });
660
+ if (!abstractSelection) {
661
+ this.selectionChangeEvent.next(null);
662
+ connector.setSelection(null);
663
+ return;
664
+ }
665
+ const { focus, anchor } = this.getPositionByRange(abstractSelection);
666
+ if (focus && anchor) {
667
+ let start = anchor;
668
+ let end = focus;
669
+ if (isFocusStart) {
670
+ start = focus;
671
+ end = anchor;
672
+ }
673
+ if (nativeRange.startContainer !== start.node || nativeRange.startOffset !== start.offset) {
674
+ nativeRange.setStart(start.node, start.offset);
675
+ }
676
+ if (nativeRange.endContainer !== end.node || nativeRange.endOffset !== end.offset) {
677
+ nativeRange.setEnd(end.node, end.offset);
678
+ }
679
+ connector.setSelection(abstractSelection);
680
+ if (selection.isCollapsed && (rawRange.startContainer !== start.node || rawRange.startOffset !== start.offset || rawRange.endContainer !== end.node || rawRange.endOffset !== end.offset)) {
681
+ rawRange.setStart(start.node, start.offset);
682
+ rawRange.setEnd(end.node, end.offset);
683
+ }
684
+ this.selectionChangeEvent.next(nativeRange);
685
+ } else {
686
+ connector.setSelection(null);
687
+ }
688
+ return;
689
+ }
690
+ connector.setSelection(null);
691
+ }
692
+ findSelectedNodeAndOffset(slot, offset) {
693
+ const prev = slot.getContentAtIndex(offset - 1);
694
+ const nodes = this.domAdapter.getNodesBySlot(slot);
695
+ if (prev) {
696
+ if (typeof prev !== "string") {
697
+ const nativeNode = this.domAdapter.getNativeNodeByComponent(prev);
698
+ return {
699
+ node: nativeNode.parentNode,
700
+ offset: Array.from(nativeNode.parentNode.childNodes).indexOf(nativeNode) + 1
701
+ };
702
+ } else if (prev === "\n") {
703
+ for (const node of nodes) {
704
+ if (node instanceof Text) {
705
+ continue;
706
+ }
707
+ if (node.nodeName === "BR") {
708
+ const position = this.domAdapter.getLocationByNativeNode(node);
709
+ if (position) {
710
+ if (position.endIndex === offset) {
711
+ const parentNode = node.parentNode;
712
+ return {
713
+ node: parentNode,
714
+ offset: Array.from(parentNode.childNodes).indexOf(node) + 1
715
+ };
716
+ }
717
+ }
718
+ }
719
+ }
720
+ }
721
+ }
722
+ const current = slot.getContentAtIndex(offset);
723
+ if (current && typeof current !== "string") {
724
+ const nativeNode = this.domAdapter.getNativeNodeByComponent(current);
725
+ return {
726
+ node: nativeNode.parentNode,
727
+ offset: Array.from(nativeNode.parentNode.childNodes).indexOf(nativeNode)
728
+ };
729
+ }
730
+ for (const node of nodes) {
731
+ if (node instanceof Element) {
732
+ if (node.tagName === "BR") {
733
+ const position2 = this.domAdapter.getLocationByNativeNode(node);
734
+ if (position2) {
735
+ if (position2.startIndex === offset) {
736
+ const parentNode = node.parentNode;
737
+ return {
738
+ node: parentNode,
739
+ offset: Array.from(parentNode.childNodes).indexOf(node)
740
+ };
741
+ }
742
+ }
743
+ }
744
+ continue;
745
+ }
746
+ const position = this.domAdapter.getLocationByNativeNode(node);
747
+ if (position) {
748
+ if (offset >= position.startIndex && offset <= position.endIndex) {
749
+ return {
750
+ node,
751
+ offset: offset - position.startIndex
752
+ };
753
+ }
754
+ }
755
+ }
756
+ return null;
757
+ }
758
+ getCorrectedPosition(node, offset, toAfter, excludeNodes = []) {
759
+ excludeNodes.push(node);
760
+ if (node.nodeType === Node.ELEMENT_NODE) {
761
+ const containerPosition = this.domAdapter.getLocationByNativeNode(node);
762
+ const childNode = node.childNodes[offset];
763
+ if (childNode) {
764
+ const childPosition = this.domAdapter.getLocationByNativeNode(childNode);
765
+ if (childPosition) {
766
+ if (containerPosition) {
767
+ return {
768
+ slot: childPosition.slot,
769
+ offset: childPosition.startIndex
770
+ };
771
+ }
772
+ return this.findFocusNode(childNode, toAfter, excludeNodes);
773
+ }
774
+ return this.findFocusNode(childNode, toAfter, excludeNodes);
775
+ }
776
+ const prevNode = node.childNodes[offset - 1];
777
+ if (prevNode) {
778
+ const prevPosition = this.domAdapter.getLocationByNativeNode(prevNode);
779
+ if (prevPosition && containerPosition) {
780
+ return {
781
+ slot: prevPosition.slot,
782
+ offset: prevPosition.endIndex
783
+ };
784
+ }
785
+ }
786
+ if (containerPosition) {
787
+ return {
788
+ slot: containerPosition.slot,
789
+ offset: containerPosition.endIndex
790
+ };
791
+ }
792
+ const nextNode = toAfter ? node.nextSibling : node.previousSibling;
793
+ if (nextNode) {
794
+ return this.findFocusNode(nextNode, toAfter, excludeNodes);
795
+ }
796
+ return this.findFocusNodeByParent(node, toAfter, excludeNodes);
797
+ } else if (node.nodeType === Node.TEXT_NODE) {
798
+ const containerPosition = this.domAdapter.getLocationByNativeNode(node);
799
+ if (containerPosition) {
800
+ return {
801
+ slot: containerPosition.slot,
802
+ offset: containerPosition.startIndex + offset
803
+ };
804
+ }
805
+ const nextNode = toAfter ? node.nextSibling : node.previousSibling;
806
+ if (nextNode) {
807
+ return this.findFocusNode(nextNode, toAfter, excludeNodes);
808
+ }
809
+ return this.findFocusNodeByParent(node, toAfter, excludeNodes);
810
+ }
811
+ return null;
812
+ }
813
+ findFocusNode(node, toAfter = false, excludeNodes = []) {
814
+ if (excludeNodes.includes(node)) {
815
+ const next = toAfter ? node.nextSibling : node.previousSibling;
816
+ if (next) {
817
+ return this.findFocusNode(next, toAfter, excludeNodes);
818
+ }
819
+ return this.findFocusNodeByParent(node, toAfter, excludeNodes);
820
+ }
821
+ excludeNodes.push(node);
822
+ const position = this.domAdapter.getLocationByNativeNode(node);
823
+ if (position) {
824
+ return {
825
+ slot: position.slot,
826
+ offset: toAfter ? position.startIndex : position.endIndex
827
+ };
828
+ }
829
+ const firstChild = toAfter ? node.firstChild : node.lastChild;
830
+ if (firstChild) {
831
+ return this.findFocusNode(firstChild, toAfter, excludeNodes);
832
+ }
833
+ const nextSibling = toAfter ? node.nextSibling : node.previousSibling;
834
+ if (nextSibling) {
835
+ return this.findFocusNode(nextSibling, toAfter, excludeNodes);
836
+ }
837
+ return this.findFocusNodeByParent(node, toAfter, excludeNodes);
838
+ }
839
+ findFocusNodeByParent(node, toAfter, excludeNodes) {
840
+ const parentNode = node.parentNode;
841
+ if (parentNode) {
842
+ const parentPosition = this.domAdapter.getLocationByNativeNode(parentNode);
843
+ if (parentPosition) {
844
+ return {
845
+ slot: parentPosition.slot,
846
+ offset: toAfter ? parentPosition.endIndex : parentPosition.startIndex
847
+ };
848
+ }
849
+ excludeNodes.push(node);
850
+ return this.findFocusNode(parentNode, toAfter, excludeNodes);
851
+ }
852
+ return null;
853
+ }
854
+ };
855
+ exports.SelectionBridge = __decorateClass$3([
856
+ core.Injectable(),
857
+ __decorateParam$1(0, core.Inject(EDITOR_OPTIONS))
858
+ ], exports.SelectionBridge);
859
+ class Input {
860
+ }
861
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
862
+ var __decorateClass$2 = (decorators, target, key, kind) => {
863
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
864
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
865
+ if (decorator = decorators[i])
866
+ result = decorator(result) || result;
867
+ return result;
868
+ };
869
+ const iframeHTML = `
4
870
  <!DOCTYPE html>
5
871
  <html>
6
872
  <head>
@@ -18,5 +884,1515 @@
18
884
  <body>
19
885
  </body>
20
886
  </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;
887
+ `;
888
+ class ExperimentalCaret {
889
+ constructor(domRenderer, scheduler, editorMask) {
890
+ this.domRenderer = domRenderer;
891
+ this.scheduler = scheduler;
892
+ this.editorMask = editorMask;
893
+ this.onPositionChange = this.positionChangeEvent.pipe(stream.distinctUntilChanged());
894
+ this.onStyleChange = this.styleChangeEvent.asObservable();
895
+ this.elementRef = createElement("div", {
896
+ styles: {
897
+ position: "absolute",
898
+ width: "2px",
899
+ pointerEvents: "none"
900
+ },
901
+ children: [
902
+ this.caret = createElement("span", {
903
+ styles: {
904
+ width: "100%",
905
+ height: "100%",
906
+ position: "absolute",
907
+ left: 0,
908
+ top: 0
909
+ }
910
+ })
911
+ ]
912
+ });
913
+ this.subscription.add(
914
+ stream.fromEvent(document, "mousedown").subscribe(() => {
915
+ this.flashing = false;
916
+ }),
917
+ stream.fromEvent(document, "mouseup").subscribe(() => {
918
+ this.flashing = true;
919
+ })
920
+ );
921
+ this.editorMask.appendChild(this.elementRef);
922
+ }
923
+ domRenderer;
924
+ scheduler;
925
+ editorMask;
926
+ onPositionChange;
927
+ onStyleChange;
928
+ elementRef;
929
+ changeFromSelf = false;
930
+ getLimit = function() {
931
+ return {
932
+ top: 0,
933
+ bottom: document.documentElement.clientHeight
934
+ };
935
+ };
936
+ get rect() {
937
+ return this.caret.getBoundingClientRect();
938
+ }
939
+ timer = null;
940
+ caret;
941
+ set display(v) {
942
+ this._display = v;
943
+ this.caret.style.visibility = v ? "visible" : "hidden";
944
+ }
945
+ get display() {
946
+ return this._display;
947
+ }
948
+ _display = true;
949
+ flashing = true;
950
+ subscription = new stream.Subscription();
951
+ positionChangeEvent = new stream.Subject();
952
+ styleChangeEvent = new stream.Subject();
953
+ oldRange = null;
954
+ refresh() {
955
+ if (this.oldRange) {
956
+ this.show(this.oldRange, false);
957
+ }
958
+ }
959
+ show(range, restart) {
960
+ this.oldRange = range;
961
+ if (restart || this.scheduler.lastChangesHasLocalUpdate) {
962
+ clearTimeout(this.timer);
963
+ }
964
+ this.updateCursorPosition(range);
965
+ if (range.collapsed) {
966
+ if (restart || this.scheduler.lastChangesHasLocalUpdate) {
967
+ this.display = true;
968
+ const toggleShowHide = () => {
969
+ this.display = !this.display || !this.flashing;
970
+ this.timer = setTimeout(toggleShowHide, 400);
971
+ };
972
+ clearTimeout(this.timer);
973
+ this.timer = setTimeout(toggleShowHide, 400);
974
+ }
975
+ } else {
976
+ this.display = false;
977
+ clearTimeout(this.timer);
978
+ }
979
+ }
980
+ hide() {
981
+ this.display = false;
982
+ clearTimeout(this.timer);
983
+ this.positionChangeEvent.next(null);
984
+ }
985
+ destroy() {
986
+ clearTimeout(this.timer);
987
+ this.subscription.unsubscribe();
988
+ }
989
+ updateCursorPosition(nativeRange) {
990
+ const startContainer = nativeRange.startContainer;
991
+ const node = startContainer.nodeType === Node.ELEMENT_NODE ? startContainer : startContainer.parentNode;
992
+ if (node?.nodeType !== Node.ELEMENT_NODE) {
993
+ this.positionChangeEvent.next(null);
994
+ return;
995
+ }
996
+ const compositionNode = this.domRenderer.compositionNode;
997
+ if (compositionNode) {
998
+ nativeRange = nativeRange.cloneRange();
999
+ nativeRange.selectNodeContents(compositionNode);
1000
+ nativeRange.collapse();
1001
+ }
1002
+ const rect = getLayoutRectByRange(nativeRange);
1003
+ const { fontSize, lineHeight, color, writingMode } = getComputedStyle(node);
1004
+ let height;
1005
+ if (isNaN(+lineHeight)) {
1006
+ const f = parseFloat(lineHeight);
1007
+ if (isNaN(f)) {
1008
+ height = parseFloat(fontSize);
1009
+ } else {
1010
+ height = f;
1011
+ }
1012
+ } else {
1013
+ height = parseFloat(fontSize) * parseFloat(lineHeight);
1014
+ }
1015
+ const boxHeight = Math.max(Math.floor(Math.max(height, rect.height)), 12);
1016
+ let rectTop = rect.top;
1017
+ if (rect.height < height) {
1018
+ rectTop -= (height - rect.height) / 2;
1019
+ }
1020
+ rectTop = Math.floor(rectTop);
1021
+ const containerRect = this.editorMask.getBoundingClientRect();
1022
+ const top = Math.floor(rectTop - containerRect.top);
1023
+ const left = Math.floor(rect.left + rect.width / 2 - containerRect.left);
1024
+ let rotate = 0;
1025
+ if (nativeRange.collapsed) {
1026
+ rotate = Math.round(Math.atan2(rect.width, rect.height) * 180 / Math.PI);
1027
+ if (rotate !== 0) {
1028
+ const hackEle = document.createElement("span");
1029
+ hackEle.style.cssText = "display: inline-block; width: 10px; height: 10px; position: relative; contain: layout style size; writing-mode: inherit";
1030
+ const pointEle = document.createElement("span");
1031
+ pointEle.style.cssText = "position: absolute; left: 0; top: 0; width:0;height:0";
1032
+ hackEle.append(pointEle);
1033
+ node.append(hackEle);
1034
+ const p1 = pointEle.getBoundingClientRect();
1035
+ pointEle.style.right = "0";
1036
+ pointEle.style.left = "";
1037
+ const p2 = pointEle.getBoundingClientRect();
1038
+ const x = p1.x - p2.x;
1039
+ const y = p1.y - p2.y;
1040
+ rotate = Math.atan2(y, x) * 180 / Math.PI;
1041
+ hackEle.remove();
1042
+ }
1043
+ }
1044
+ if (writingMode === "vertical-lr" || writingMode === "vertical-rl") {
1045
+ rotate += 90;
1046
+ }
1047
+ Object.assign(this.elementRef.style, {
1048
+ left: left + "px",
1049
+ top: top + "px",
1050
+ height: boxHeight + "px",
1051
+ lineHeight: boxHeight + "px",
1052
+ fontSize,
1053
+ transform: `rotate(${rotate}deg)`
1054
+ });
1055
+ this.caret.style.backgroundColor = color === "rgba(0, 0, 0, 0)" ? "#000" : color;
1056
+ this.styleChangeEvent.next({
1057
+ height: boxHeight + "px",
1058
+ lineHeight: boxHeight + "px",
1059
+ fontSize
1060
+ });
1061
+ this.positionChangeEvent.next({
1062
+ left,
1063
+ top: rectTop,
1064
+ height: boxHeight
1065
+ });
1066
+ if (this.changeFromSelf) {
1067
+ this.changeFromSelf = false;
1068
+ const selfRect = this.elementRef.getBoundingClientRect();
1069
+ const scrollContainer = this.getScrollContainer(startContainer);
1070
+ const scrollRect = scrollContainer === document.documentElement ? { top: 0, bottom: document.documentElement.clientHeight } : scrollContainer.getBoundingClientRect();
1071
+ const limit = this.getLimit();
1072
+ const top2 = Math.max(limit.top, scrollRect.top);
1073
+ const bottom = Math.min(limit.bottom, scrollRect.bottom);
1074
+ if (selfRect.top < top2) {
1075
+ scrollContainer.scrollTop -= top2 - selfRect.top;
1076
+ } else if (selfRect.bottom > bottom) {
1077
+ scrollContainer.scrollTop += selfRect.bottom - bottom;
1078
+ }
1079
+ }
1080
+ }
1081
+ getScrollContainer(container) {
1082
+ while (container) {
1083
+ if (container instanceof Element) {
1084
+ const styles = getComputedStyle(container);
1085
+ if (styles.overflow !== "visible" || styles.overflowX !== "visible" || styles.overflowY !== "visible") {
1086
+ return container;
1087
+ }
1088
+ }
1089
+ container = container.parentNode;
1090
+ }
1091
+ return document.documentElement;
1092
+ }
1093
+ }
1094
+ exports.MagicInput = class MagicInput extends Input {
1095
+ // 有 bug 版本搜狗拼音
1096
+ constructor(domAdapter, parser, keyboard, commander, selection, controller, scheduler, textbus) {
1097
+ super();
1098
+ this.domAdapter = domAdapter;
1099
+ this.parser = parser;
1100
+ this.keyboard = keyboard;
1101
+ this.commander = commander;
1102
+ this.selection = selection;
1103
+ this.controller = controller;
1104
+ this.scheduler = scheduler;
1105
+ this.textbus = textbus;
1106
+ this.caret = new ExperimentalCaret(this.domAdapter, this.scheduler, this.textbus.get(VIEW_MASK));
1107
+ this.onReady = new Promise((resolve) => {
1108
+ this.subscription.add(
1109
+ stream.fromEvent(this.container, "load").subscribe(() => {
1110
+ const doc = this.container.contentDocument;
1111
+ doc.open();
1112
+ doc.write(iframeHTML);
1113
+ doc.close();
1114
+ this.doc = doc;
1115
+ this.init();
1116
+ resolve();
1117
+ }),
1118
+ controller.onReadonlyStateChange.subscribe(() => {
1119
+ if (controller.readonly) {
1120
+ this.blur();
1121
+ }
1122
+ })
1123
+ );
1124
+ });
1125
+ this.caret.elementRef.append(this.container);
1126
+ }
1127
+ domAdapter;
1128
+ parser;
1129
+ keyboard;
1130
+ commander;
1131
+ selection;
1132
+ controller;
1133
+ scheduler;
1134
+ textbus;
1135
+ composition = false;
1136
+ onReady;
1137
+ caret;
1138
+ set disabled(b) {
1139
+ this._disabled = b;
1140
+ if (b && this.textarea) {
1141
+ this.textarea.disabled = b;
1142
+ }
1143
+ }
1144
+ get disabled() {
1145
+ return this._disabled;
1146
+ }
1147
+ isSafari = isSafari();
1148
+ isFirefox = isFirefox();
1149
+ isMac = isMac();
1150
+ isWindows = isWindows();
1151
+ _disabled = false;
1152
+ container = this.createEditableFrame();
1153
+ subscription = new stream.Subscription();
1154
+ doc;
1155
+ textarea = null;
1156
+ isFocus = false;
1157
+ nativeFocus = false;
1158
+ ignoreComposition = false;
1159
+ focus(range, restart) {
1160
+ if (!this.disabled) {
1161
+ this.caret.show(range, restart);
1162
+ }
1163
+ if (this.controller.readonly) {
1164
+ return;
1165
+ }
1166
+ if (!this.isFocus) {
1167
+ this.textarea?.focus();
1168
+ setTimeout(() => {
1169
+ if (!this.nativeFocus && this.isFocus) {
1170
+ this.reInit();
1171
+ }
1172
+ });
1173
+ }
1174
+ this.isFocus = true;
1175
+ }
1176
+ blur() {
1177
+ this.caret.hide();
1178
+ this.textarea?.blur();
1179
+ this.isFocus = false;
1180
+ }
1181
+ destroy() {
1182
+ this.caret.destroy();
1183
+ this.subscription.unsubscribe();
1184
+ }
1185
+ reInit(delay = false) {
1186
+ this.subscription.unsubscribe();
1187
+ this.textarea?.parentNode?.removeChild(this.textarea);
1188
+ this.subscription = new stream.Subscription();
1189
+ this.init();
1190
+ if (delay) {
1191
+ setTimeout(() => {
1192
+ this.textarea?.focus();
1193
+ });
1194
+ } else {
1195
+ this.textarea?.focus();
1196
+ }
1197
+ }
1198
+ init() {
1199
+ const doc = this.doc;
1200
+ const contentBody = doc.body;
1201
+ const textarea = doc.createElement("textarea");
1202
+ textarea.disabled = this.disabled;
1203
+ contentBody.appendChild(textarea);
1204
+ this.textarea = textarea;
1205
+ this.subscription.add(
1206
+ stream.fromEvent(textarea, "blur").subscribe(() => {
1207
+ this.isFocus = false;
1208
+ this.nativeFocus = false;
1209
+ this.caret.hide();
1210
+ if (this.domAdapter.composition) {
1211
+ const slot = this.domAdapter.composition.slot;
1212
+ this.domAdapter.composition = null;
1213
+ this.domAdapter.compositionNode = null;
1214
+ slot.__changeMarker__.forceMarkDirtied();
1215
+ }
1216
+ }),
1217
+ stream.fromEvent(textarea, "focus").subscribe(() => {
1218
+ this.nativeFocus = true;
1219
+ }),
1220
+ this.caret.onStyleChange.subscribe((style) => {
1221
+ Object.assign(textarea.style, style);
1222
+ })
1223
+ );
1224
+ this.handleInput(textarea);
1225
+ this.handleShortcut(textarea);
1226
+ this.handleDefaultActions(textarea);
1227
+ }
1228
+ handleDefaultActions(textarea) {
1229
+ this.subscription.add(
1230
+ stream.fromEvent(isFirefox() ? textarea : document, "copy").subscribe((ev) => {
1231
+ this.copyHandler(ev);
1232
+ }),
1233
+ stream.fromEvent(textarea, "paste").subscribe((ev) => {
1234
+ this.pasteHandler(ev);
1235
+ })
1236
+ );
1237
+ }
1238
+ copyHandler(ev) {
1239
+ const selection = this.selection;
1240
+ if (!selection.isSelected) {
1241
+ return;
1242
+ }
1243
+ if (selection.startSlot === selection.endSlot && selection.endOffset - selection.startOffset === 1) {
1244
+ const content = selection.startSlot.getContentAtIndex(selection.startOffset);
1245
+ if (typeof content === "object") {
1246
+ const clipboardData = ev.clipboardData;
1247
+ const nativeSelection = document.getSelection();
1248
+ const range = nativeSelection.getRangeAt(0);
1249
+ const div = document.createElement("div");
1250
+ const fragment = range.cloneContents();
1251
+ div.append(fragment);
1252
+ clipboardData.setData("text/html", div.innerHTML);
1253
+ clipboardData.setData("text", div.innerText);
1254
+ ev.preventDefault();
1255
+ }
1256
+ }
1257
+ }
1258
+ pasteHandler(ev) {
1259
+ const text = ev.clipboardData.getData("Text");
1260
+ const types = Array.from(ev.clipboardData.types || []);
1261
+ const files = Array.from(ev.clipboardData.files);
1262
+ if (types.every((type) => type === "Files") && files.length) {
1263
+ Promise.all(files.filter((i) => {
1264
+ return /image/i.test(i.type);
1265
+ }).map((item) => {
1266
+ const reader = new FileReader();
1267
+ return new Promise((resolve) => {
1268
+ reader.onload = (event) => {
1269
+ resolve(event.target.result);
1270
+ };
1271
+ reader.readAsDataURL(item);
1272
+ });
1273
+ })).then((urls) => {
1274
+ const html = urls.map((i) => {
1275
+ return `<img src=${i}>`;
1276
+ }).join("");
1277
+ this.paste(html, text);
1278
+ });
1279
+ ev.preventDefault();
1280
+ return;
1281
+ }
1282
+ const div = this.doc.createElement("div");
1283
+ div.style.cssText = "width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0";
1284
+ div.contentEditable = "true";
1285
+ this.doc.body.appendChild(div);
1286
+ div.focus();
1287
+ setTimeout(() => {
1288
+ this.doc.body.removeChild(div);
1289
+ div.style.cssText = "";
1290
+ this.paste(div, text);
1291
+ });
1292
+ }
1293
+ paste(dom, text) {
1294
+ const slot = this.parser.parse(dom, new core$1.Slot([
1295
+ core$1.ContentType.BlockComponent,
1296
+ core$1.ContentType.InlineComponent,
1297
+ core$1.ContentType.Text
1298
+ ]));
1299
+ this.commander.paste(slot, text);
1300
+ }
1301
+ handleShortcut(textarea) {
1302
+ let isWriting = false;
1303
+ let isIgnore = false;
1304
+ this.subscription.add(
1305
+ stream.fromEvent(textarea, "compositionstart").subscribe(() => {
1306
+ isWriting = true;
1307
+ }),
1308
+ stream.fromEvent(textarea, "compositionend").subscribe(() => {
1309
+ isWriting = false;
1310
+ }),
1311
+ stream.fromEvent(textarea, "beforeinput").subscribe((ev) => {
1312
+ this.ignoreComposition = false;
1313
+ if (this.isSafari) {
1314
+ if (ev.inputType === "insertFromComposition") {
1315
+ isIgnore = true;
1316
+ }
1317
+ }
1318
+ }),
1319
+ stream.fromEvent(textarea, "keydown").pipe(stream.filter(() => {
1320
+ if (this.isSafari && isIgnore) {
1321
+ isIgnore = false;
1322
+ return false;
1323
+ }
1324
+ return !isWriting;
1325
+ })).subscribe((ev) => {
1326
+ this.ignoreComposition = false;
1327
+ let key = ev.key;
1328
+ const keys = ")!@#$%^Z&*(";
1329
+ const b = key === "Process" && /Digit\d/.test(ev.code) && ev.shiftKey;
1330
+ if (b) {
1331
+ key = keys.charAt(+ev.code.substring(5));
1332
+ ev.preventDefault();
1333
+ }
1334
+ this.caret.changeFromSelf = true;
1335
+ const is = this.keyboard.execShortcut({
1336
+ key,
1337
+ altKey: ev.altKey,
1338
+ shiftKey: ev.shiftKey,
1339
+ modKey: this.isMac ? ev.metaKey : ev.ctrlKey,
1340
+ agent: {
1341
+ key: ev.key,
1342
+ code: ev.code,
1343
+ keyCode: ev.keyCode
1344
+ }
1345
+ });
1346
+ if (is) {
1347
+ this.ignoreComposition = true;
1348
+ ev.preventDefault();
1349
+ } else {
1350
+ this.caret.changeFromSelf = false;
1351
+ }
1352
+ })
1353
+ );
1354
+ }
1355
+ handleInput(textarea) {
1356
+ let startIndex = 0;
1357
+ this.subscription.add(
1358
+ stream.fromEvent(textarea, "compositionstart").pipe(stream.filter(() => {
1359
+ return !this.ignoreComposition;
1360
+ })).subscribe(() => {
1361
+ if (!this.selection.isCollapsed) {
1362
+ this.caret.changeFromSelf = true;
1363
+ this.commander.delete();
1364
+ }
1365
+ this.composition = true;
1366
+ startIndex = this.selection.startOffset;
1367
+ const startSlot = this.selection.startSlot;
1368
+ const event = new core$1.Event(startSlot, {
1369
+ index: startIndex
1370
+ });
1371
+ core$1.invokeListener(startSlot.parent, "onCompositionStart", event);
1372
+ }),
1373
+ stream.fromEvent(textarea, "compositionupdate").pipe(stream.filter(() => {
1374
+ return !this.ignoreComposition;
1375
+ })).pipe(stream.distinctUntilChanged((prev, next) => {
1376
+ return prev.data !== next.data;
1377
+ })).subscribe((ev) => {
1378
+ if (ev.data === " ") {
1379
+ return;
1380
+ }
1381
+ const startSlot = this.selection.startSlot;
1382
+ this.domAdapter.composition = {
1383
+ slot: startSlot,
1384
+ text: ev.data,
1385
+ offset: ev.data.length,
1386
+ index: startIndex
1387
+ };
1388
+ this.caret.changeFromSelf = true;
1389
+ this.caret.refresh();
1390
+ const event = new core$1.Event(startSlot, {
1391
+ index: startIndex,
1392
+ data: ev.data
1393
+ });
1394
+ core$1.invokeListener(startSlot.parent, "onCompositionUpdate", event);
1395
+ startSlot.__changeMarker__.forceMarkDirtied();
1396
+ })
1397
+ );
1398
+ let isCompositionEnd = false;
1399
+ this.subscription.add(
1400
+ stream.merge(
1401
+ stream.fromEvent(textarea, "beforeinput").pipe(
1402
+ stream.filter((ev) => {
1403
+ ev.preventDefault();
1404
+ if (this.isFirefox && ev.inputType === "insertFromPaste") {
1405
+ return false;
1406
+ }
1407
+ if (this.isSafari) {
1408
+ isCompositionEnd = ev.inputType === "insertFromComposition";
1409
+ return ev.inputType === "insertText" || ev.inputType === "insertFromComposition";
1410
+ }
1411
+ return !ev.isComposing && !!ev.data;
1412
+ }),
1413
+ stream.map((ev) => {
1414
+ return ev.data;
1415
+ })
1416
+ ),
1417
+ this.isSafari ? new stream.Observable() : stream.fromEvent(textarea, "compositionend").pipe(stream.filter(() => {
1418
+ return !this.ignoreComposition;
1419
+ })).pipe(
1420
+ stream.map((ev) => {
1421
+ isCompositionEnd = true;
1422
+ ev.preventDefault();
1423
+ textarea.value = "";
1424
+ return ev.data;
1425
+ })
1426
+ )
1427
+ ).subscribe((text) => {
1428
+ this.composition = false;
1429
+ this.domAdapter.composition = null;
1430
+ if (text) {
1431
+ this.caret.changeFromSelf = true;
1432
+ this.commander.write(text);
1433
+ } else {
1434
+ this.selection.startSlot?.__changeMarker__.forceMarkDirtied();
1435
+ }
1436
+ if (isCompositionEnd) {
1437
+ const startSlot = this.selection.startSlot;
1438
+ if (startSlot) {
1439
+ const event = new core$1.Event(startSlot, null);
1440
+ core$1.invokeListener(startSlot.parent, "onCompositionEnd", event);
1441
+ }
1442
+ }
1443
+ isCompositionEnd = false;
1444
+ })
1445
+ );
1446
+ }
1447
+ createEditableFrame() {
1448
+ return createElement("iframe", {
1449
+ attrs: {
1450
+ scrolling: "no"
1451
+ },
1452
+ styles: {
1453
+ border: "none",
1454
+ width: "100%",
1455
+ display: "block",
1456
+ height: "100%",
1457
+ position: "relative",
1458
+ top: this.isWindows ? "3px" : "0"
1459
+ }
1460
+ });
1461
+ }
1462
+ };
1463
+ exports.MagicInput = __decorateClass$2([
1464
+ core.Injectable()
1465
+ ], exports.MagicInput);
1466
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
1467
+ var __decorateClass$1 = (decorators, target, key, kind) => {
1468
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
1469
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
1470
+ if (decorator = decorators[i])
1471
+ result = decorator(result) || result;
1472
+ return result;
1473
+ };
1474
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
1475
+ class CollaborateSelectionAwarenessDelegate {
1476
+ }
1477
+ exports.CollaborateCursor = class CollaborateCursor {
1478
+ constructor(textbus, nativeSelection, scheduler, selection, awarenessDelegate) {
1479
+ this.nativeSelection = nativeSelection;
1480
+ this.scheduler = scheduler;
1481
+ this.selection = selection;
1482
+ this.awarenessDelegate = awarenessDelegate;
1483
+ this.container = textbus.get(VIEW_CONTAINER);
1484
+ this.canvasContainer.append(this.canvas);
1485
+ this.host.append(this.canvasContainer, this.tooltips);
1486
+ this.container.prepend(this.host);
1487
+ this.subscription.add(this.onRectsChange.subscribe((rects) => {
1488
+ for (const rect of rects) {
1489
+ this.context.fillStyle = rect.color;
1490
+ this.context.beginPath();
1491
+ this.context.rect(rect.left, rect.top, rect.width, rect.height);
1492
+ this.context.fill();
1493
+ this.context.closePath();
1494
+ }
1495
+ }), stream.fromEvent(window, "resize").subscribe(() => {
1496
+ this.canvas.style.height = document.documentElement.clientHeight + "px";
1497
+ this.refresh();
1498
+ }), this.scheduler.onDocChanged.subscribe(() => {
1499
+ this.refresh();
1500
+ }));
1501
+ }
1502
+ nativeSelection;
1503
+ scheduler;
1504
+ selection;
1505
+ awarenessDelegate;
1506
+ host = createElement("div", {
1507
+ styles: {
1508
+ position: "absolute",
1509
+ left: 0,
1510
+ top: 0,
1511
+ width: "100%",
1512
+ height: "100%",
1513
+ pointerEvents: "none",
1514
+ zIndex: 1
1515
+ }
1516
+ });
1517
+ canvasContainer = createElement("div", {
1518
+ styles: {
1519
+ position: "absolute",
1520
+ left: 0,
1521
+ top: 0,
1522
+ width: "100%",
1523
+ height: "100%",
1524
+ overflow: "hidden"
1525
+ }
1526
+ });
1527
+ canvas = createElement("canvas", {
1528
+ styles: {
1529
+ position: "absolute",
1530
+ opacity: 0.5,
1531
+ left: 0,
1532
+ top: 0,
1533
+ width: "100%",
1534
+ height: document.documentElement.clientHeight + "px",
1535
+ pointerEvents: "none"
1536
+ }
1537
+ });
1538
+ context = this.canvas.getContext("2d");
1539
+ tooltips = createElement("div", {
1540
+ styles: {
1541
+ position: "absolute",
1542
+ left: 0,
1543
+ top: 0,
1544
+ width: "100%",
1545
+ height: "100%",
1546
+ pointerEvents: "none",
1547
+ fontSize: "12px",
1548
+ zIndex: 10
1549
+ }
1550
+ });
1551
+ onRectsChange = new stream.Subject();
1552
+ subscription = new stream.Subscription();
1553
+ selectionCursors = [];
1554
+ container;
1555
+ ratio = window.devicePixelRatio || 1;
1556
+ /**
1557
+ * 刷新协作光标,由于 Textbus 只会绘制可视区域的光标,当可视区域发生变化时,需要重新绘制
1558
+ */
1559
+ refresh() {
1560
+ this.draw(this.selectionCursors);
1561
+ }
1562
+ destroy() {
1563
+ this.subscription.unsubscribe();
1564
+ }
1565
+ /**
1566
+ * 根据远程用户光标位置,绘制协作光标
1567
+ * @param paths
1568
+ */
1569
+ draw(paths) {
1570
+ this.selectionCursors = paths;
1571
+ const containerRect = this.container.getBoundingClientRect();
1572
+ this.canvas.style.top = containerRect.top * -1 + "px";
1573
+ this.canvas.width = this.canvas.offsetWidth * this.ratio;
1574
+ this.canvas.height = this.canvas.offsetHeight * this.ratio;
1575
+ this.context.scale(this.ratio, this.ratio);
1576
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
1577
+ const users = [];
1578
+ paths.filter((i) => {
1579
+ return i.selection.anchor.length && i.selection.focus.length;
1580
+ }).forEach((item) => {
1581
+ const anchorPaths = [...item.selection.anchor];
1582
+ const focusPaths = [...item.selection.focus];
1583
+ const anchorOffset = anchorPaths.pop();
1584
+ const anchorSlot = this.selection.findSlotByPaths(anchorPaths);
1585
+ const focusOffset = focusPaths.pop();
1586
+ const focusSlot = this.selection.findSlotByPaths(focusPaths);
1587
+ if (!anchorSlot || !focusSlot) {
1588
+ return;
1589
+ }
1590
+ const { focus, anchor } = this.nativeSelection.getPositionByRange({
1591
+ focusOffset,
1592
+ anchorOffset,
1593
+ focusSlot,
1594
+ anchorSlot
1595
+ });
1596
+ if (!focus || !anchor) {
1597
+ return;
1598
+ }
1599
+ const nativeRange = document.createRange();
1600
+ try {
1601
+ nativeRange.setStart(anchor.node, anchor.offset);
1602
+ nativeRange.setEnd(focus.node, focus.offset);
1603
+ } catch (e) {
1604
+ return;
1605
+ }
1606
+ if ((anchor.node !== focus.node || anchor.offset !== focus.offset) && nativeRange.collapsed) {
1607
+ nativeRange.setStart(focus.node, focus.offset);
1608
+ nativeRange.setEnd(anchor.node, anchor.offset);
1609
+ }
1610
+ let rects = false;
1611
+ if (this.awarenessDelegate) {
1612
+ rects = this.awarenessDelegate.getRects({
1613
+ focusOffset,
1614
+ anchorOffset,
1615
+ focusSlot,
1616
+ anchorSlot
1617
+ }, nativeRange, item);
1618
+ }
1619
+ if (!rects) {
1620
+ rects = nativeRange.getClientRects();
1621
+ }
1622
+ const selectionRects = [];
1623
+ for (let i = rects.length - 1; i >= 0; i--) {
1624
+ const rect2 = rects[i];
1625
+ selectionRects.push({
1626
+ color: item.color,
1627
+ username: item.username,
1628
+ left: rect2.left - containerRect.left,
1629
+ top: rect2.top,
1630
+ width: rect2.width,
1631
+ height: rect2.height
1632
+ });
1633
+ }
1634
+ this.onRectsChange.next(selectionRects);
1635
+ const cursorRange = nativeRange.cloneRange();
1636
+ cursorRange.setStart(focus.node, focus.offset);
1637
+ cursorRange.collapse(true);
1638
+ const cursorRect = getLayoutRectByRange(cursorRange);
1639
+ const rect = {
1640
+ username: item.username,
1641
+ color: item.color,
1642
+ left: cursorRect.left - containerRect.left,
1643
+ top: cursorRect.top - containerRect.top,
1644
+ width: 1,
1645
+ height: cursorRect.height
1646
+ };
1647
+ if (rect.left < 0 || rect.top < 0 || rect.left > containerRect.width) {
1648
+ return;
1649
+ }
1650
+ users.push(rect);
1651
+ });
1652
+ this.drawUserCursor(users);
1653
+ }
1654
+ drawUserCursor(rects) {
1655
+ for (let i = 0; i < rects.length; i++) {
1656
+ const rect = rects[i];
1657
+ const { cursor, userTip, anchor } = this.getUserCursor(i);
1658
+ Object.assign(cursor.style, {
1659
+ left: rect.left + "px",
1660
+ top: rect.top + "px",
1661
+ width: rect.width + "px",
1662
+ height: rect.height + "px",
1663
+ background: rect.color,
1664
+ display: "block"
1665
+ });
1666
+ anchor.style.background = rect.color;
1667
+ userTip.innerText = rect.username;
1668
+ userTip.style.background = rect.color;
1669
+ }
1670
+ for (let i = rects.length; i < this.tooltips.children.length; i++) {
1671
+ this.tooltips.removeChild(this.tooltips.children[i]);
1672
+ }
1673
+ }
1674
+ getUserCursor(index) {
1675
+ let child = this.tooltips.children[index];
1676
+ if (child) {
1677
+ const anchor2 = child.children[0];
1678
+ return {
1679
+ cursor: child,
1680
+ anchor: anchor2,
1681
+ userTip: anchor2.children[0]
1682
+ };
1683
+ }
1684
+ const userTip = createElement("span", {
1685
+ styles: {
1686
+ position: "absolute",
1687
+ left: "50%",
1688
+ transform: "translateX(-50%)",
1689
+ marginBottom: "2px",
1690
+ bottom: "100%",
1691
+ whiteSpace: "nowrap",
1692
+ color: "#fff",
1693
+ boxShadow: "0 1px 2px rgba(0,0,0,.1)",
1694
+ opacity: 0.8,
1695
+ borderRadius: "3px",
1696
+ padding: "3px 5px",
1697
+ pointerEvents: "none"
1698
+ }
1699
+ });
1700
+ const anchor = createElement("span", {
1701
+ styles: {
1702
+ position: "absolute",
1703
+ top: "-2px",
1704
+ left: "-2px",
1705
+ width: "5px",
1706
+ height: "5px",
1707
+ borderRadius: "50%",
1708
+ pointerEvents: "auto",
1709
+ pointer: "cursor"
1710
+ },
1711
+ children: [userTip]
1712
+ });
1713
+ child = createElement("span", {
1714
+ styles: {
1715
+ position: "absolute"
1716
+ },
1717
+ children: [
1718
+ anchor
1719
+ ]
1720
+ });
1721
+ this.tooltips.append(child);
1722
+ return {
1723
+ cursor: child,
1724
+ anchor,
1725
+ userTip
1726
+ };
1727
+ }
1728
+ };
1729
+ exports.CollaborateCursor = __decorateClass$1([
1730
+ core.Injectable(),
1731
+ __decorateParam(4, core.Optional())
1732
+ ], exports.CollaborateCursor);
1733
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
1734
+ var __decorateClass = (decorators, target, key, kind) => {
1735
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
1736
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
1737
+ if (decorator = decorators[i])
1738
+ result = decorator(result) || result;
1739
+ return result;
1740
+ };
1741
+ class NativeCaret {
1742
+ onPositionChange;
1743
+ set nativeRange(range) {
1744
+ this._nativeRange = range;
1745
+ if (range) {
1746
+ const r = range.cloneRange();
1747
+ r.collapse(true);
1748
+ const rect = getLayoutRectByRange(r);
1749
+ this.positionChangeEvent.next({
1750
+ left: rect.left,
1751
+ top: rect.top,
1752
+ height: rect.height
1753
+ });
1754
+ } else {
1755
+ this.positionChangeEvent.next(null);
1756
+ }
1757
+ }
1758
+ get nativeRange() {
1759
+ return this._nativeRange;
1760
+ }
1761
+ get rect() {
1762
+ if (this.nativeRange) {
1763
+ const range = this.nativeRange.cloneRange();
1764
+ range.collapse(true);
1765
+ return getLayoutRectByRange(range);
1766
+ }
1767
+ return {
1768
+ left: 0,
1769
+ top: 0,
1770
+ width: 0,
1771
+ height: 0
1772
+ };
1773
+ }
1774
+ _nativeRange = null;
1775
+ subs = [];
1776
+ positionChangeEvent = new stream.Subject();
1777
+ constructor() {
1778
+ this.onPositionChange = this.positionChangeEvent.pipe(stream.distinctUntilChanged());
1779
+ }
1780
+ refresh() {
1781
+ }
1782
+ destroy() {
1783
+ this.subs.forEach((i) => i.unsubscribe());
1784
+ this.subs = [];
1785
+ }
1786
+ }
1787
+ exports.NativeInput = class NativeInput extends Input {
1788
+ // 有 bug 版本搜狗拼音
1789
+ constructor(textbus, parser, selection, keyboard, domAdapter, commander, controller) {
1790
+ super();
1791
+ this.parser = parser;
1792
+ this.selection = selection;
1793
+ this.keyboard = keyboard;
1794
+ this.domAdapter = domAdapter;
1795
+ this.commander = commander;
1796
+ this.controller = controller;
1797
+ this.documentView = textbus.get(VIEW_DOCUMENT);
1798
+ if (!controller.readonly) {
1799
+ this.documentView.contentEditable = "true";
1800
+ }
1801
+ this.subscription.add(
1802
+ controller.onReadonlyStateChange.subscribe(() => {
1803
+ this.documentView.contentEditable = controller.readonly ? "false" : "true";
1804
+ })
1805
+ );
1806
+ this.handleShortcut(this.documentView);
1807
+ this.handleInput(this.documentView);
1808
+ this.handleDefaultActions(this.documentView);
1809
+ }
1810
+ parser;
1811
+ selection;
1812
+ keyboard;
1813
+ domAdapter;
1814
+ commander;
1815
+ controller;
1816
+ caret = new NativeCaret();
1817
+ composition = false;
1818
+ // compositionState: CompositionState | null = null
1819
+ onReady = Promise.resolve();
1820
+ set disabled(b) {
1821
+ this._disabled = b;
1822
+ if (this.controller.readonly) {
1823
+ this.documentView.contentEditable = "false";
1824
+ return;
1825
+ }
1826
+ this.documentView.contentEditable = b ? "false" : "true";
1827
+ }
1828
+ get disabled() {
1829
+ return this._disabled;
1830
+ }
1831
+ _disabled = false;
1832
+ documentView;
1833
+ nativeSelection = document.getSelection();
1834
+ subscription = new stream.Subscription();
1835
+ nativeRange = null;
1836
+ isSafari = isSafari();
1837
+ isMac = isMac();
1838
+ isMobileBrowser = isMobileBrowser();
1839
+ ignoreComposition = false;
1840
+ focus(nativeRange) {
1841
+ if (this.controller.readonly) {
1842
+ return;
1843
+ }
1844
+ this.caret.nativeRange = nativeRange;
1845
+ this.nativeRange = nativeRange;
1846
+ }
1847
+ blur() {
1848
+ if (this.nativeRange && this.nativeSelection.rangeCount > 0) {
1849
+ const current = this.nativeSelection.getRangeAt(0);
1850
+ if (current === this.nativeRange) {
1851
+ this.nativeSelection.removeAllRanges();
1852
+ this.nativeRange = null;
1853
+ return;
1854
+ }
1855
+ }
1856
+ }
1857
+ destroy() {
1858
+ this.caret.destroy();
1859
+ this.subscription.unsubscribe();
1860
+ }
1861
+ handleDefaultActions(textarea) {
1862
+ this.subscription.add(
1863
+ stream.fromEvent(isFirefox() ? textarea : document, "copy").subscribe((ev) => {
1864
+ this.copyHandler(ev);
1865
+ }),
1866
+ stream.fromEvent(textarea, "paste").subscribe((ev) => {
1867
+ this.pasteHandler(ev);
1868
+ })
1869
+ );
1870
+ }
1871
+ copyHandler(ev) {
1872
+ const selection = this.selection;
1873
+ if (!selection.isSelected) {
1874
+ return;
1875
+ }
1876
+ if (selection.startSlot === selection.endSlot && selection.endOffset - selection.startOffset === 1) {
1877
+ const content = selection.startSlot.getContentAtIndex(selection.startOffset);
1878
+ if (typeof content === "object") {
1879
+ const clipboardData = ev.clipboardData;
1880
+ const nativeSelection = document.getSelection();
1881
+ const range = nativeSelection.getRangeAt(0);
1882
+ const div = document.createElement("div");
1883
+ const fragment = range.cloneContents();
1884
+ div.append(fragment);
1885
+ clipboardData.setData("text/html", div.innerHTML);
1886
+ clipboardData.setData("text", div.innerText);
1887
+ ev.preventDefault();
1888
+ }
1889
+ }
1890
+ }
1891
+ pasteHandler(ev) {
1892
+ const text = ev.clipboardData.getData("Text");
1893
+ const types = Array.from(ev.clipboardData.types || []);
1894
+ const files = Array.from(ev.clipboardData.files);
1895
+ if (types.every((type) => type === "Files") && files.length) {
1896
+ Promise.all(files.filter((i) => {
1897
+ return /image/i.test(i.type);
1898
+ }).map((item) => {
1899
+ const reader = new FileReader();
1900
+ return new Promise((resolve) => {
1901
+ reader.onload = (event) => {
1902
+ resolve(event.target.result);
1903
+ };
1904
+ reader.readAsDataURL(item);
1905
+ });
1906
+ })).then((urls) => {
1907
+ const html = urls.map((i) => {
1908
+ return `<img src=${i}>`;
1909
+ }).join("");
1910
+ this.paste(html, text);
1911
+ });
1912
+ ev.preventDefault();
1913
+ return;
1914
+ }
1915
+ const div = document.createElement("div");
1916
+ div.style.cssText = "width:1px; height:10px; overflow: hidden; position: fixed; left: 50%; top: 50%; opacity:0";
1917
+ div.contentEditable = "true";
1918
+ document.body.appendChild(div);
1919
+ div.focus();
1920
+ setTimeout(() => {
1921
+ document.body.removeChild(div);
1922
+ div.style.cssText = "";
1923
+ this.paste(div, text);
1924
+ });
1925
+ }
1926
+ paste(dom, text) {
1927
+ const slot = this.parser.parse(dom, new core$1.Slot([
1928
+ core$1.ContentType.BlockComponent,
1929
+ core$1.ContentType.InlineComponent,
1930
+ core$1.ContentType.Text
1931
+ ]));
1932
+ this.commander.paste(slot, text);
1933
+ }
1934
+ handleShortcut(input) {
1935
+ let isWriting = false;
1936
+ let isIgnore = false;
1937
+ this.subscription.add(
1938
+ stream.fromEvent(input, "compositionstart").subscribe(() => {
1939
+ isWriting = true;
1940
+ }),
1941
+ stream.fromEvent(input, "compositionend").subscribe(() => {
1942
+ isWriting = false;
1943
+ }),
1944
+ stream.fromEvent(input, "beforeinput").subscribe((ev) => {
1945
+ if (this.isSafari) {
1946
+ if (ev.inputType === "insertFromComposition") {
1947
+ isIgnore = true;
1948
+ }
1949
+ }
1950
+ }),
1951
+ stream.fromEvent(input, "keydown").pipe(stream.filter(() => {
1952
+ if (this.isSafari && isIgnore) {
1953
+ isIgnore = false;
1954
+ return false;
1955
+ }
1956
+ return !isWriting;
1957
+ })).subscribe((ev) => {
1958
+ this.ignoreComposition = false;
1959
+ let key = ev.key;
1960
+ const keys = ")!@#$%^Z&*(";
1961
+ const b = key === "Process" && /Digit\d/.test(ev.code) && ev.shiftKey;
1962
+ if (b) {
1963
+ key = keys.charAt(+ev.code.substring(5));
1964
+ ev.preventDefault();
1965
+ }
1966
+ const is = this.keyboard.execShortcut({
1967
+ key,
1968
+ altKey: ev.altKey,
1969
+ shiftKey: ev.shiftKey,
1970
+ modKey: this.isMac ? ev.metaKey : ev.ctrlKey,
1971
+ agent: {
1972
+ key: ev.key,
1973
+ keyCode: ev.keyCode,
1974
+ code: ev.code
1975
+ }
1976
+ });
1977
+ if (is) {
1978
+ this.ignoreComposition = true;
1979
+ ev.preventDefault();
1980
+ }
1981
+ })
1982
+ );
1983
+ }
1984
+ handleInput(input) {
1985
+ if (this.isMobileBrowser) {
1986
+ this.handleMobileInput(input);
1987
+ } else {
1988
+ this.handlePCInput(input);
1989
+ }
1990
+ }
1991
+ handleMobileInput(input) {
1992
+ let isCompositionStart = true;
1993
+ let startIndex;
1994
+ const compositionStart = () => {
1995
+ this.composition = true;
1996
+ startIndex = this.selection.startOffset;
1997
+ const startSlot = this.selection.startSlot;
1998
+ const event = new core$1.Event(startSlot, {
1999
+ index: startIndex
2000
+ });
2001
+ core$1.invokeListener(startSlot.parent, "onCompositionStart", event);
2002
+ };
2003
+ const compositionUpdate = (data) => {
2004
+ const startSlot = this.selection.startSlot;
2005
+ const event = new core$1.Event(startSlot, {
2006
+ index: startIndex,
2007
+ data
2008
+ });
2009
+ core$1.invokeListener(startSlot.parent, "onCompositionUpdate", event);
2010
+ };
2011
+ const compositionEnd = (data) => {
2012
+ this.composition = false;
2013
+ if (data) {
2014
+ this.commander.write(data);
2015
+ }
2016
+ const startSlot = this.selection.startSlot;
2017
+ if (startSlot) {
2018
+ const event = new core$1.Event(startSlot, null);
2019
+ core$1.invokeListener(startSlot.parent, "onCompositionEnd", event);
2020
+ }
2021
+ };
2022
+ this.subscription.add(
2023
+ stream.fromEvent(input, "compositionstart").subscribe(() => {
2024
+ compositionStart();
2025
+ }),
2026
+ stream.fromEvent(input, "compositionupdate").subscribe((ev) => {
2027
+ compositionUpdate(ev.data);
2028
+ }),
2029
+ stream.fromEvent(input, "compositionend").subscribe((ev) => {
2030
+ compositionEnd(ev.data);
2031
+ const startContainer = this.nativeSelection.focusNode;
2032
+ if (startContainer instanceof Text && startContainer.textContent === ev.data) {
2033
+ startContainer.remove();
2034
+ }
2035
+ }),
2036
+ stream.fromEvent(input, "beforeinput").subscribe((ev) => {
2037
+ switch (ev.inputType) {
2038
+ case "insertText":
2039
+ if (ev.data) {
2040
+ this.commander.write(ev.data);
2041
+ ev.preventDefault();
2042
+ }
2043
+ break;
2044
+ case "insertCompositionText":
2045
+ if (isCompositionStart) {
2046
+ isCompositionStart = false;
2047
+ compositionStart();
2048
+ } else {
2049
+ compositionUpdate(ev.data || "");
2050
+ }
2051
+ break;
2052
+ case "deleteCompositionText":
2053
+ this.composition = false;
2054
+ break;
2055
+ case "deleteContentBackward": {
2056
+ this.composition = false;
2057
+ const range = ev.getTargetRanges()[0];
2058
+ if (!range) {
2059
+ break;
2060
+ }
2061
+ const location = this.domAdapter.getLocationByNativeNode(range.startContainer);
2062
+ const startSlot = this.selection.startSlot;
2063
+ if (startSlot) {
2064
+ this.selection.setBaseAndExtent(
2065
+ startSlot,
2066
+ location.startIndex + range.startOffset,
2067
+ startSlot,
2068
+ location.startIndex + range.endOffset
2069
+ );
2070
+ this.commander.delete();
2071
+ }
2072
+ break;
2073
+ }
2074
+ case "insertReplacementText": {
2075
+ this.composition = false;
2076
+ const range = ev.getTargetRanges()[0];
2077
+ const location = this.domAdapter.getLocationByNativeNode(range.startContainer);
2078
+ const startSlot = this.selection.startSlot;
2079
+ this.selection.setBaseAndExtent(
2080
+ startSlot,
2081
+ location.startIndex + range.startOffset,
2082
+ startSlot,
2083
+ location.startIndex + range.endOffset
2084
+ );
2085
+ this.commander.delete();
2086
+ const text = ev.dataTransfer?.getData("text") || ev.data || null;
2087
+ if (text) {
2088
+ this.commander.write(text);
2089
+ }
2090
+ break;
2091
+ }
2092
+ }
2093
+ })
2094
+ );
2095
+ }
2096
+ handlePCInput(input) {
2097
+ let startIndex = 0;
2098
+ let isCompositionEnd = false;
2099
+ this.subscription.add(
2100
+ stream.fromEvent(input, "compositionstart").pipe(stream.filter(() => {
2101
+ return !this.ignoreComposition;
2102
+ })).subscribe(() => {
2103
+ this.composition = true;
2104
+ startIndex = this.selection.startOffset;
2105
+ const startSlot = this.selection.startSlot;
2106
+ const event = new core$1.Event(startSlot, {
2107
+ index: startIndex
2108
+ });
2109
+ core$1.invokeListener(startSlot.parent, "onCompositionStart", event);
2110
+ }),
2111
+ stream.fromEvent(input, "compositionupdate").pipe(stream.filter(() => {
2112
+ return !this.ignoreComposition;
2113
+ })).subscribe((ev) => {
2114
+ const startSlot = this.selection.startSlot;
2115
+ const event = new core$1.Event(startSlot, {
2116
+ index: startIndex,
2117
+ data: ev.data
2118
+ });
2119
+ core$1.invokeListener(startSlot.parent, "onCompositionUpdate", event);
2120
+ }),
2121
+ stream.merge(
2122
+ stream.fromEvent(input, "beforeinput").pipe(
2123
+ stream.map((ev) => {
2124
+ ev.preventDefault();
2125
+ if (ev.inputType === "insertCompositionText") {
2126
+ return null;
2127
+ }
2128
+ if (ev.inputType === "insertReplacementText") {
2129
+ const range = ev.getTargetRanges()[0];
2130
+ const location = this.domAdapter.getLocationByNativeNode(range.startContainer);
2131
+ const startSlot = this.selection.startSlot;
2132
+ this.selection.setBaseAndExtent(
2133
+ startSlot,
2134
+ location.startIndex + range.startOffset,
2135
+ startSlot,
2136
+ location.startIndex + range.endOffset
2137
+ );
2138
+ this.commander.delete();
2139
+ return ev.dataTransfer?.getData("text") || ev.data || null;
2140
+ }
2141
+ isCompositionEnd = ev.inputType === "insertFromComposition";
2142
+ if (isCompositionEnd && this.composition) {
2143
+ return null;
2144
+ }
2145
+ if (this.isSafari) {
2146
+ if (ev.inputType === "insertText" || isCompositionEnd) {
2147
+ return ev.data;
2148
+ }
2149
+ }
2150
+ if (!ev.isComposing && !!ev.data) {
2151
+ return ev.data;
2152
+ }
2153
+ return null;
2154
+ }),
2155
+ stream.filter((text) => {
2156
+ return text;
2157
+ })
2158
+ ),
2159
+ this.isSafari ? new stream.Observable() : stream.fromEvent(input, "compositionend").pipe(stream.filter(() => {
2160
+ return !this.ignoreComposition;
2161
+ })).pipe(
2162
+ stream.filter(() => {
2163
+ return this.composition;
2164
+ }),
2165
+ stream.map((ev) => {
2166
+ isCompositionEnd = true;
2167
+ ev.preventDefault();
2168
+ return ev.data;
2169
+ }),
2170
+ stream.filter(() => {
2171
+ const b = this.ignoreComposition;
2172
+ this.ignoreComposition = false;
2173
+ return !b;
2174
+ })
2175
+ )
2176
+ ).subscribe((text) => {
2177
+ this.composition = false;
2178
+ if (text) {
2179
+ const startContainer = this.nativeSelection.focusNode;
2180
+ if (startContainer instanceof Text && startContainer.textContent === text) {
2181
+ startContainer.remove();
2182
+ }
2183
+ this.commander.write(text);
2184
+ }
2185
+ if (isCompositionEnd) {
2186
+ const startSlot = this.selection.startSlot;
2187
+ if (startSlot) {
2188
+ const event = new core$1.Event(startSlot, null);
2189
+ core$1.invokeListener(startSlot.parent, "onCompositionEnd", event);
2190
+ }
2191
+ }
2192
+ isCompositionEnd = false;
2193
+ })
2194
+ );
2195
+ }
2196
+ };
2197
+ exports.NativeInput = __decorateClass([
2198
+ core.Injectable()
2199
+ ], exports.NativeInput);
2200
+ class DomAdapter extends core$1.Adapter {
2201
+ onViewUpdated = new stream.Subject();
2202
+ host = createElement("div", {
2203
+ styles: {
2204
+ cursor: "text",
2205
+ wordBreak: "break-all",
2206
+ boxSizing: "border-box",
2207
+ flex: 1,
2208
+ outline: "none"
2209
+ },
2210
+ attrs: {
2211
+ "data-textbus-view": VIEW_DOCUMENT
2212
+ },
2213
+ props: {
2214
+ id: "textbus-" + Number((Math.random() + "").substring(2)).toString(16)
2215
+ }
2216
+ });
2217
+ }
2218
+ const browserErrorFn = core$1.makeError("BrowserModule");
2219
+ class BrowserModule {
2220
+ constructor(config) {
2221
+ this.config = config;
2222
+ const { mask, wrapper } = BrowserModule.createLayout();
2223
+ wrapper.prepend(config.adapter.host);
2224
+ if (config.minHeight) {
2225
+ config.adapter.host.style.minHeight = config.minHeight;
2226
+ }
2227
+ this.providers = [
2228
+ {
2229
+ provide: EDITOR_OPTIONS,
2230
+ useValue: config
2231
+ },
2232
+ {
2233
+ provide: VIEW_CONTAINER,
2234
+ useValue: wrapper
2235
+ },
2236
+ {
2237
+ provide: VIEW_DOCUMENT,
2238
+ useValue: config.adapter.host
2239
+ },
2240
+ {
2241
+ provide: VIEW_MASK,
2242
+ useValue: mask
2243
+ },
2244
+ {
2245
+ provide: core$1.NativeSelectionBridge,
2246
+ useExisting: exports.SelectionBridge
2247
+ },
2248
+ {
2249
+ provide: Input,
2250
+ useClass: config.useContentEditable ? exports.NativeInput : exports.MagicInput
2251
+ },
2252
+ {
2253
+ provide: core$1.Adapter,
2254
+ useValue: config.adapter
2255
+ },
2256
+ {
2257
+ provide: DomAdapter,
2258
+ useValue: config.adapter
2259
+ },
2260
+ {
2261
+ provide: core$1.FocusManager,
2262
+ useFactory: (input) => {
2263
+ const focusEvent = new stream.Subject();
2264
+ const blurEvent = new stream.Subject();
2265
+ input.caret.onPositionChange.pipe(
2266
+ stream.map((p) => !!p),
2267
+ stream.distinctUntilChanged()
2268
+ ).subscribe((b) => {
2269
+ if (b) {
2270
+ focusEvent.next();
2271
+ } else {
2272
+ blurEvent.next();
2273
+ }
2274
+ });
2275
+ return {
2276
+ onFocus: focusEvent,
2277
+ onBlur: blurEvent
2278
+ };
2279
+ },
2280
+ deps: [Input]
2281
+ },
2282
+ exports.Parser,
2283
+ exports.SelectionBridge,
2284
+ exports.CollaborateCursor
2285
+ ];
2286
+ this.workbench = wrapper;
2287
+ }
2288
+ config;
2289
+ providers;
2290
+ workbench;
2291
+ /**
2292
+ * 解析 HTML 并返回一个组件实例
2293
+ * @param html 要解析的 HTML
2294
+ * @param rootComponentLoader 文档根组件加载器
2295
+ * @param textbus
2296
+ */
2297
+ readDocumentByHTML(html, rootComponentLoader, textbus) {
2298
+ const parser = textbus.get(exports.Parser);
2299
+ const doc = parser.parseDoc(html, rootComponentLoader);
2300
+ if (doc instanceof core$1.Component) {
2301
+ return doc;
2302
+ }
2303
+ throw browserErrorFn("rootComponentLoader must return a component instance.");
2304
+ }
2305
+ /**
2306
+ * 将组件数据解析到组件实例中
2307
+ * @param data 要解析的 JSON 数据
2308
+ * @param rootComponent 根组件
2309
+ * @param textbus
2310
+ */
2311
+ readDocumentByComponentLiteral(data, rootComponent, textbus) {
2312
+ const registry = textbus.get(core$1.Registry);
2313
+ return registry.createComponentByFactory(data, rootComponent);
2314
+ }
2315
+ async setup(textbus) {
2316
+ const host = this.config.renderTo();
2317
+ if (!(host instanceof HTMLElement)) {
2318
+ throw browserErrorFn("view container is not a HTMLElement");
2319
+ }
2320
+ host.append(this.workbench);
2321
+ await textbus.get(Input).onReady;
2322
+ return () => {
2323
+ this.workbench.remove();
2324
+ };
2325
+ }
2326
+ onAfterStartup(textbus) {
2327
+ if (this.config.autoFocus) {
2328
+ textbus.focus();
2329
+ }
2330
+ }
2331
+ onDestroy(textbus) {
2332
+ textbus.get(Input).destroy();
2333
+ textbus.get(exports.SelectionBridge).destroy();
2334
+ textbus.get(exports.CollaborateCursor).destroy();
2335
+ }
2336
+ static createLayout() {
2337
+ const mask = createElement("div", {
2338
+ attrs: {
2339
+ "data-textbus-view": VIEW_MASK
2340
+ },
2341
+ styles: {
2342
+ position: "absolute",
2343
+ left: 0,
2344
+ right: 0,
2345
+ top: 0,
2346
+ bottom: 0,
2347
+ pointerEvents: "none"
2348
+ // overflow: 'hidden'
2349
+ }
2350
+ });
2351
+ const maskWrapper = createElement("div", {
2352
+ styles: {
2353
+ position: "absolute",
2354
+ left: 0,
2355
+ right: 0,
2356
+ top: 0,
2357
+ bottom: 0,
2358
+ margin: "0 -2px",
2359
+ zIndex: 1,
2360
+ pointerEvents: "none",
2361
+ overflow: "hidden"
2362
+ },
2363
+ children: [mask]
2364
+ });
2365
+ const wrapper = createElement("div", {
2366
+ attrs: {
2367
+ "data-textbus-view": VIEW_CONTAINER
2368
+ },
2369
+ styles: {
2370
+ display: "flex",
2371
+ minHeight: "100%",
2372
+ position: "relative",
2373
+ flexDirection: "column"
2374
+ },
2375
+ children: [maskWrapper]
2376
+ });
2377
+ return {
2378
+ wrapper,
2379
+ mask
2380
+ };
2381
+ }
2382
+ }
2383
+ exports.BrowserModule = BrowserModule;
2384
+ exports.CollaborateSelectionAwarenessDelegate = CollaborateSelectionAwarenessDelegate;
2385
+ exports.DomAdapter = DomAdapter;
2386
+ exports.EDITOR_OPTIONS = EDITOR_OPTIONS;
2387
+ exports.Input = Input;
2388
+ exports.VIEW_CONTAINER = VIEW_CONTAINER;
2389
+ exports.VIEW_DOCUMENT = VIEW_DOCUMENT;
2390
+ exports.VIEW_MASK = VIEW_MASK;
2391
+ exports.createElement = createElement;
2392
+ exports.getLayoutRectByRange = getLayoutRectByRange;
2393
+ exports.isFirefox = isFirefox;
2394
+ exports.isMac = isMac;
2395
+ exports.isMobileBrowser = isMobileBrowser;
2396
+ exports.isSafari = isSafari;
2397
+ exports.isWindows = isWindows;
22
2398
  //# sourceMappingURL=index.js.map