@textbus/platform-browser 3.0.0-alpha.58 → 3.0.0-alpha.59
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.
@@ -1,18 +1,13 @@
|
|
1
1
|
import { Observable } from '@tanbo/stream';
|
2
2
|
import { Injector } from '@tanbo/di';
|
3
|
-
import { Commander, Controller, Keyboard, Scheduler, Selection
|
3
|
+
import { Commander, Controller, Keyboard, Scheduler, Selection } from '@textbus/core';
|
4
4
|
import { Parser } from '../dom-support/parser';
|
5
|
-
import { Caret, CaretPosition, Input, Scroller } from './types';
|
5
|
+
import { Caret, CaretPosition, CompositionState, Input, Scroller } from './types';
|
6
6
|
interface CaretStyle {
|
7
7
|
height: string;
|
8
8
|
lineHeight: string;
|
9
9
|
fontSize: string;
|
10
10
|
}
|
11
|
-
interface CompositionState {
|
12
|
-
slot: Slot;
|
13
|
-
index: number;
|
14
|
-
data: string;
|
15
|
-
}
|
16
11
|
declare class ExperimentalCaret implements Caret {
|
17
12
|
private scheduler;
|
18
13
|
private editorMask;
|
@@ -54,6 +49,7 @@ export declare class MagicInput extends Input {
|
|
54
49
|
private scheduler;
|
55
50
|
private injector;
|
56
51
|
composition: boolean;
|
52
|
+
compositionState: CompositionState | null;
|
57
53
|
onReady: Promise<void>;
|
58
54
|
caret: ExperimentalCaret;
|
59
55
|
set disabled(b: boolean);
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { Injector } from '@tanbo/di';
|
2
2
|
import { Observable } from '@tanbo/stream';
|
3
3
|
import { Commander, Controller, Keyboard, Scheduler, Selection } from '@textbus/core';
|
4
|
-
import { Caret, CaretPosition, Input, Scroller } from './types';
|
4
|
+
import { Caret, CaretPosition, CompositionState, Input, Scroller } from './types';
|
5
5
|
import { Parser } from '../dom-support/parser';
|
6
6
|
declare class NativeCaret implements Caret {
|
7
7
|
private scheduler;
|
@@ -33,6 +33,7 @@ export declare class NativeInput extends Input {
|
|
33
33
|
private controller;
|
34
34
|
caret: NativeCaret;
|
35
35
|
composition: boolean;
|
36
|
+
compositionState: CompositionState | null;
|
36
37
|
onReady: Promise<void>;
|
37
38
|
set disabled(b: boolean);
|
38
39
|
get disabled(): boolean;
|
package/bundles/core/types.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ComponentLiteral, Module, TextbusConfig } from '@textbus/core';
|
1
|
+
import { ComponentLiteral, Module, Slot, TextbusConfig } from '@textbus/core';
|
2
2
|
import { Observable } from '@tanbo/stream';
|
3
3
|
import { FormatLoader, ComponentLoader, AttributeLoader } from '../dom-support/parser';
|
4
4
|
import { Rect } from '../_utils/uikit';
|
@@ -51,8 +51,14 @@ export interface Caret {
|
|
51
51
|
refresh(isFixedCaret: boolean): void;
|
52
52
|
correctScrollTop(scroller: Scroller): void;
|
53
53
|
}
|
54
|
+
export interface CompositionState {
|
55
|
+
slot: Slot;
|
56
|
+
index: number;
|
57
|
+
data: string;
|
58
|
+
}
|
54
59
|
export declare abstract class Input {
|
55
60
|
abstract composition: boolean;
|
61
|
+
abstract compositionState: CompositionState | null;
|
56
62
|
abstract onReady: Promise<void>;
|
57
63
|
abstract caret: Caret;
|
58
64
|
abstract disabled: boolean;
|
package/bundles/index.esm.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import 'reflect-metadata';
|
2
2
|
import { InjectionToken, Injectable, Inject, Injector, Optional } from '@tanbo/di';
|
3
|
-
import { VTextNode, VElement, Controller, Selection, RootComponentRef, Renderer, Scheduler, Slot, ContentType, Keyboard, Commander, makeError, Starter, NativeRenderer, NativeSelectionBridge, OutputRenderer, Registry,
|
3
|
+
import { VTextNode, VElement, Controller, Selection, RootComponentRef, Renderer, Scheduler, Slot, ContentType, Event, invokeListener, Keyboard, Commander, makeError, Starter, NativeRenderer, NativeSelectionBridge, OutputRenderer, Registry, History } from '@textbus/core';
|
4
4
|
import { Subject, filter, fromEvent, Subscription, merge, map, Observable, distinctUntilChanged } from '@tanbo/stream';
|
5
5
|
|
6
6
|
function createElement(tagName, options = {}) {
|
@@ -1585,6 +1585,7 @@ let MagicInput = class MagicInput extends Input {
|
|
1585
1585
|
this.scheduler = scheduler;
|
1586
1586
|
this.injector = injector;
|
1587
1587
|
this.composition = false;
|
1588
|
+
this.compositionState = null;
|
1588
1589
|
this.caret = new ExperimentalCaret(this.scheduler, this.injector.get(VIEW_MASK));
|
1589
1590
|
this.isSafari = isSafari();
|
1590
1591
|
this.isFirefox = isFirefox();
|
@@ -1718,7 +1719,7 @@ let MagicInput = class MagicInput extends Input {
|
|
1718
1719
|
setTimeout(() => {
|
1719
1720
|
let html = div.innerHTML;
|
1720
1721
|
if (!html && text && this.isFirefox) {
|
1721
|
-
html =
|
1722
|
+
html = text;
|
1722
1723
|
}
|
1723
1724
|
this.handlePaste(html, text);
|
1724
1725
|
this.doc.body.removeChild(div);
|
@@ -1775,32 +1776,46 @@ let MagicInput = class MagicInput extends Input {
|
|
1775
1776
|
let startIndex = 0;
|
1776
1777
|
this.subscription.add(fromEvent(textarea, 'compositionstart').subscribe(() => {
|
1777
1778
|
this.composition = true;
|
1779
|
+
this.caret.compositionState = this.compositionState = null;
|
1778
1780
|
startIndex = this.selection.startOffset;
|
1781
|
+
const startSlot = this.selection.startSlot;
|
1782
|
+
const event = new Event(startSlot, {
|
1783
|
+
index: startIndex
|
1784
|
+
});
|
1785
|
+
invokeListener(startSlot.parent, 'onCompositionStart', event);
|
1779
1786
|
}), fromEvent(textarea, 'compositionupdate').subscribe(ev => {
|
1780
1787
|
if (ev.data === ' ') {
|
1781
1788
|
// 处理搜狗五笔不符合 composition 事件预期,会意外跳光标的问题
|
1782
1789
|
return;
|
1783
1790
|
}
|
1784
|
-
this.
|
1785
|
-
|
1791
|
+
const startSlot = this.selection.startSlot;
|
1792
|
+
this.caret.compositionState = this.compositionState = {
|
1793
|
+
slot: startSlot,
|
1786
1794
|
index: startIndex,
|
1787
1795
|
data: ev.data
|
1788
1796
|
};
|
1789
1797
|
this.caret.refresh(true);
|
1790
|
-
|
1791
|
-
|
1792
|
-
|
1793
|
-
|
1798
|
+
const event = new Event(startSlot, {
|
1799
|
+
index: startIndex,
|
1800
|
+
data: ev.data
|
1801
|
+
});
|
1802
|
+
invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
1794
1803
|
}));
|
1804
|
+
let isCompositionEnd = false;
|
1795
1805
|
this.subscription.add(merge(fromEvent(textarea, 'beforeinput').pipe(filter(ev => {
|
1796
1806
|
ev.preventDefault();
|
1807
|
+
if (this.isFirefox && ev.inputType === 'insertFromPaste') {
|
1808
|
+
return false;
|
1809
|
+
}
|
1797
1810
|
if (this.isSafari) {
|
1811
|
+
isCompositionEnd = ev.inputType === 'insertFromComposition';
|
1798
1812
|
return ev.inputType === 'insertText' || ev.inputType === 'insertFromComposition';
|
1799
1813
|
}
|
1800
1814
|
return !ev.isComposing && !!ev.data;
|
1801
1815
|
}), map(ev => {
|
1802
1816
|
return ev.data;
|
1803
1817
|
})), this.isSafari ? new Observable() : fromEvent(textarea, 'compositionend').pipe(map(ev => {
|
1818
|
+
isCompositionEnd = true;
|
1804
1819
|
ev.preventDefault();
|
1805
1820
|
textarea.value = '';
|
1806
1821
|
return ev.data;
|
@@ -1809,10 +1824,21 @@ let MagicInput = class MagicInput extends Input {
|
|
1809
1824
|
this.isSougouPinYin = false;
|
1810
1825
|
return !b;
|
1811
1826
|
}))).subscribe(text => {
|
1827
|
+
var _a;
|
1812
1828
|
this.composition = false;
|
1829
|
+
this.caret.compositionState = this.compositionState = null;
|
1830
|
+
(_a = this.caret.compositionElement.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.caret.compositionElement);
|
1813
1831
|
if (text) {
|
1814
1832
|
this.commander.write(text);
|
1815
1833
|
}
|
1834
|
+
if (isCompositionEnd) {
|
1835
|
+
const startSlot = this.selection.startSlot;
|
1836
|
+
if (startSlot) {
|
1837
|
+
const event = new Event(startSlot, null);
|
1838
|
+
invokeListener(startSlot.parent, 'onCompositionEnd', event);
|
1839
|
+
}
|
1840
|
+
}
|
1841
|
+
isCompositionEnd = false;
|
1816
1842
|
}));
|
1817
1843
|
}
|
1818
1844
|
createEditableFrame() {
|
@@ -1965,6 +1991,7 @@ let NativeInput = class NativeInput extends Input {
|
|
1965
1991
|
this.controller = controller;
|
1966
1992
|
this.caret = new NativeCaret(this.scheduler);
|
1967
1993
|
this.composition = false;
|
1994
|
+
this.compositionState = null;
|
1968
1995
|
this.onReady = Promise.resolve();
|
1969
1996
|
this._disabled = false;
|
1970
1997
|
this.nativeSelection = document.getSelection();
|
@@ -2107,17 +2134,40 @@ let NativeInput = class NativeInput extends Input {
|
|
2107
2134
|
}));
|
2108
2135
|
}
|
2109
2136
|
handleInput(input) {
|
2137
|
+
let startIndex = 0;
|
2138
|
+
let isCompositionEnd = false;
|
2110
2139
|
this.subscription.add(fromEvent(input, 'compositionstart').subscribe(() => {
|
2111
2140
|
this.composition = true;
|
2141
|
+
this.compositionState = null;
|
2142
|
+
startIndex = this.selection.startOffset;
|
2143
|
+
const startSlot = this.selection.startSlot;
|
2144
|
+
const event = new Event(startSlot, {
|
2145
|
+
index: startIndex
|
2146
|
+
});
|
2147
|
+
invokeListener(startSlot.parent, 'onCompositionStart', event);
|
2148
|
+
}), fromEvent(input, 'compositionupdate').subscribe(ev => {
|
2149
|
+
const startSlot = this.selection.startSlot;
|
2150
|
+
this.compositionState = {
|
2151
|
+
slot: startSlot,
|
2152
|
+
index: startIndex,
|
2153
|
+
data: ev.data
|
2154
|
+
};
|
2155
|
+
const event = new Event(startSlot, {
|
2156
|
+
index: startIndex,
|
2157
|
+
data: ev.data
|
2158
|
+
});
|
2159
|
+
invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
2112
2160
|
}), merge(fromEvent(input, 'beforeinput').pipe(filter(ev => {
|
2113
2161
|
ev.preventDefault();
|
2114
2162
|
if (this.isSafari) {
|
2163
|
+
isCompositionEnd = ev.inputType === 'insertFromComposition';
|
2115
2164
|
return ev.inputType === 'insertText' || ev.inputType === 'insertFromComposition';
|
2116
2165
|
}
|
2117
2166
|
return !ev.isComposing && !!ev.data;
|
2118
2167
|
}), map(ev => {
|
2119
2168
|
return ev.data;
|
2120
2169
|
})), this.isSafari ? new Observable() : fromEvent(input, 'compositionend').pipe(map(ev => {
|
2170
|
+
isCompositionEnd = true;
|
2121
2171
|
ev.preventDefault();
|
2122
2172
|
return ev.data;
|
2123
2173
|
}), filter(() => {
|
@@ -2126,9 +2176,18 @@ let NativeInput = class NativeInput extends Input {
|
|
2126
2176
|
return !b;
|
2127
2177
|
}))).subscribe(text => {
|
2128
2178
|
this.composition = false;
|
2179
|
+
this.compositionState = null;
|
2129
2180
|
if (text) {
|
2130
2181
|
this.commander.write(text);
|
2131
2182
|
}
|
2183
|
+
if (isCompositionEnd) {
|
2184
|
+
const startSlot = this.selection.startSlot;
|
2185
|
+
if (startSlot) {
|
2186
|
+
const event = new Event(startSlot, null);
|
2187
|
+
invokeListener(startSlot.parent, 'onCompositionEnd', event);
|
2188
|
+
}
|
2189
|
+
}
|
2190
|
+
isCompositionEnd = false;
|
2132
2191
|
}));
|
2133
2192
|
}
|
2134
2193
|
};
|
package/bundles/index.js
CHANGED
@@ -1587,6 +1587,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1587
1587
|
this.scheduler = scheduler;
|
1588
1588
|
this.injector = injector;
|
1589
1589
|
this.composition = false;
|
1590
|
+
this.compositionState = null;
|
1590
1591
|
this.caret = new ExperimentalCaret(this.scheduler, this.injector.get(VIEW_MASK));
|
1591
1592
|
this.isSafari = isSafari();
|
1592
1593
|
this.isFirefox = isFirefox();
|
@@ -1720,7 +1721,7 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1720
1721
|
setTimeout(() => {
|
1721
1722
|
let html = div.innerHTML;
|
1722
1723
|
if (!html && text && this.isFirefox) {
|
1723
|
-
html =
|
1724
|
+
html = text;
|
1724
1725
|
}
|
1725
1726
|
this.handlePaste(html, text);
|
1726
1727
|
this.doc.body.removeChild(div);
|
@@ -1777,32 +1778,46 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1777
1778
|
let startIndex = 0;
|
1778
1779
|
this.subscription.add(stream.fromEvent(textarea, 'compositionstart').subscribe(() => {
|
1779
1780
|
this.composition = true;
|
1781
|
+
this.caret.compositionState = this.compositionState = null;
|
1780
1782
|
startIndex = this.selection.startOffset;
|
1783
|
+
const startSlot = this.selection.startSlot;
|
1784
|
+
const event = new core.Event(startSlot, {
|
1785
|
+
index: startIndex
|
1786
|
+
});
|
1787
|
+
core.invokeListener(startSlot.parent, 'onCompositionStart', event);
|
1781
1788
|
}), stream.fromEvent(textarea, 'compositionupdate').subscribe(ev => {
|
1782
1789
|
if (ev.data === ' ') {
|
1783
1790
|
// 处理搜狗五笔不符合 composition 事件预期,会意外跳光标的问题
|
1784
1791
|
return;
|
1785
1792
|
}
|
1786
|
-
this.
|
1787
|
-
|
1793
|
+
const startSlot = this.selection.startSlot;
|
1794
|
+
this.caret.compositionState = this.compositionState = {
|
1795
|
+
slot: startSlot,
|
1788
1796
|
index: startIndex,
|
1789
1797
|
data: ev.data
|
1790
1798
|
};
|
1791
1799
|
this.caret.refresh(true);
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1800
|
+
const event = new core.Event(startSlot, {
|
1801
|
+
index: startIndex,
|
1802
|
+
data: ev.data
|
1803
|
+
});
|
1804
|
+
core.invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
1796
1805
|
}));
|
1806
|
+
let isCompositionEnd = false;
|
1797
1807
|
this.subscription.add(stream.merge(stream.fromEvent(textarea, 'beforeinput').pipe(stream.filter(ev => {
|
1798
1808
|
ev.preventDefault();
|
1809
|
+
if (this.isFirefox && ev.inputType === 'insertFromPaste') {
|
1810
|
+
return false;
|
1811
|
+
}
|
1799
1812
|
if (this.isSafari) {
|
1813
|
+
isCompositionEnd = ev.inputType === 'insertFromComposition';
|
1800
1814
|
return ev.inputType === 'insertText' || ev.inputType === 'insertFromComposition';
|
1801
1815
|
}
|
1802
1816
|
return !ev.isComposing && !!ev.data;
|
1803
1817
|
}), stream.map(ev => {
|
1804
1818
|
return ev.data;
|
1805
1819
|
})), this.isSafari ? new stream.Observable() : stream.fromEvent(textarea, 'compositionend').pipe(stream.map(ev => {
|
1820
|
+
isCompositionEnd = true;
|
1806
1821
|
ev.preventDefault();
|
1807
1822
|
textarea.value = '';
|
1808
1823
|
return ev.data;
|
@@ -1811,10 +1826,21 @@ exports.MagicInput = class MagicInput extends Input {
|
|
1811
1826
|
this.isSougouPinYin = false;
|
1812
1827
|
return !b;
|
1813
1828
|
}))).subscribe(text => {
|
1829
|
+
var _a;
|
1814
1830
|
this.composition = false;
|
1831
|
+
this.caret.compositionState = this.compositionState = null;
|
1832
|
+
(_a = this.caret.compositionElement.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(this.caret.compositionElement);
|
1815
1833
|
if (text) {
|
1816
1834
|
this.commander.write(text);
|
1817
1835
|
}
|
1836
|
+
if (isCompositionEnd) {
|
1837
|
+
const startSlot = this.selection.startSlot;
|
1838
|
+
if (startSlot) {
|
1839
|
+
const event = new core.Event(startSlot, null);
|
1840
|
+
core.invokeListener(startSlot.parent, 'onCompositionEnd', event);
|
1841
|
+
}
|
1842
|
+
}
|
1843
|
+
isCompositionEnd = false;
|
1818
1844
|
}));
|
1819
1845
|
}
|
1820
1846
|
createEditableFrame() {
|
@@ -1967,6 +1993,7 @@ exports.NativeInput = class NativeInput extends Input {
|
|
1967
1993
|
this.controller = controller;
|
1968
1994
|
this.caret = new NativeCaret(this.scheduler);
|
1969
1995
|
this.composition = false;
|
1996
|
+
this.compositionState = null;
|
1970
1997
|
this.onReady = Promise.resolve();
|
1971
1998
|
this._disabled = false;
|
1972
1999
|
this.nativeSelection = document.getSelection();
|
@@ -2109,17 +2136,40 @@ exports.NativeInput = class NativeInput extends Input {
|
|
2109
2136
|
}));
|
2110
2137
|
}
|
2111
2138
|
handleInput(input) {
|
2139
|
+
let startIndex = 0;
|
2140
|
+
let isCompositionEnd = false;
|
2112
2141
|
this.subscription.add(stream.fromEvent(input, 'compositionstart').subscribe(() => {
|
2113
2142
|
this.composition = true;
|
2143
|
+
this.compositionState = null;
|
2144
|
+
startIndex = this.selection.startOffset;
|
2145
|
+
const startSlot = this.selection.startSlot;
|
2146
|
+
const event = new core.Event(startSlot, {
|
2147
|
+
index: startIndex
|
2148
|
+
});
|
2149
|
+
core.invokeListener(startSlot.parent, 'onCompositionStart', event);
|
2150
|
+
}), stream.fromEvent(input, 'compositionupdate').subscribe(ev => {
|
2151
|
+
const startSlot = this.selection.startSlot;
|
2152
|
+
this.compositionState = {
|
2153
|
+
slot: startSlot,
|
2154
|
+
index: startIndex,
|
2155
|
+
data: ev.data
|
2156
|
+
};
|
2157
|
+
const event = new core.Event(startSlot, {
|
2158
|
+
index: startIndex,
|
2159
|
+
data: ev.data
|
2160
|
+
});
|
2161
|
+
core.invokeListener(startSlot.parent, 'onCompositionUpdate', event);
|
2114
2162
|
}), stream.merge(stream.fromEvent(input, 'beforeinput').pipe(stream.filter(ev => {
|
2115
2163
|
ev.preventDefault();
|
2116
2164
|
if (this.isSafari) {
|
2165
|
+
isCompositionEnd = ev.inputType === 'insertFromComposition';
|
2117
2166
|
return ev.inputType === 'insertText' || ev.inputType === 'insertFromComposition';
|
2118
2167
|
}
|
2119
2168
|
return !ev.isComposing && !!ev.data;
|
2120
2169
|
}), stream.map(ev => {
|
2121
2170
|
return ev.data;
|
2122
2171
|
})), this.isSafari ? new stream.Observable() : stream.fromEvent(input, 'compositionend').pipe(stream.map(ev => {
|
2172
|
+
isCompositionEnd = true;
|
2123
2173
|
ev.preventDefault();
|
2124
2174
|
return ev.data;
|
2125
2175
|
}), stream.filter(() => {
|
@@ -2128,9 +2178,18 @@ exports.NativeInput = class NativeInput extends Input {
|
|
2128
2178
|
return !b;
|
2129
2179
|
}))).subscribe(text => {
|
2130
2180
|
this.composition = false;
|
2181
|
+
this.compositionState = null;
|
2131
2182
|
if (text) {
|
2132
2183
|
this.commander.write(text);
|
2133
2184
|
}
|
2185
|
+
if (isCompositionEnd) {
|
2186
|
+
const startSlot = this.selection.startSlot;
|
2187
|
+
if (startSlot) {
|
2188
|
+
const event = new core.Event(startSlot, null);
|
2189
|
+
core.invokeListener(startSlot.parent, 'onCompositionEnd', event);
|
2190
|
+
}
|
2191
|
+
}
|
2192
|
+
isCompositionEnd = false;
|
2134
2193
|
}));
|
2135
2194
|
}
|
2136
2195
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@textbus/platform-browser",
|
3
|
-
"version": "3.0.0-alpha.
|
3
|
+
"version": "3.0.0-alpha.59",
|
4
4
|
"description": "Textbus is a rich text editor and framework that is highly customizable and extensible to achieve rich wysiwyg effects.",
|
5
5
|
"main": "./bundles/index.js",
|
6
6
|
"module": "./bundles/index.esm.js",
|
@@ -27,7 +27,7 @@
|
|
27
27
|
"dependencies": {
|
28
28
|
"@tanbo/di": "^1.1.4",
|
29
29
|
"@tanbo/stream": "^1.1.9",
|
30
|
-
"@textbus/core": "^3.0.0-alpha.
|
30
|
+
"@textbus/core": "^3.0.0-alpha.59",
|
31
31
|
"reflect-metadata": "^0.1.13"
|
32
32
|
},
|
33
33
|
"devDependencies": {
|
@@ -48,5 +48,5 @@
|
|
48
48
|
"bugs": {
|
49
49
|
"url": "https://github.com/textbus/textbus.git/issues"
|
50
50
|
},
|
51
|
-
"gitHead": "
|
51
|
+
"gitHead": "7b4fd0eb4680416ddf112c8cec1432ea51919d19"
|
52
52
|
}
|