modern-text 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +115 -173
- package/dist/index.d.cts +25 -38
- package/dist/index.d.mts +25 -38
- package/dist/index.d.ts +25 -38
- package/dist/index.js +8 -28
- package/dist/index.mjs +115 -173
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -828,92 +828,6 @@ class Measurer {
|
|
|
828
828
|
}
|
|
829
829
|
}
|
|
830
830
|
|
|
831
|
-
class EventEmitter {
|
|
832
|
-
eventListeners = /* @__PURE__ */ new Map();
|
|
833
|
-
addEventListener(event, listener, options) {
|
|
834
|
-
const object = { value: listener, options };
|
|
835
|
-
const listeners = this.eventListeners.get(event);
|
|
836
|
-
if (!listeners) {
|
|
837
|
-
this.eventListeners.set(event, object);
|
|
838
|
-
} else if (Array.isArray(listeners)) {
|
|
839
|
-
listeners.push(object);
|
|
840
|
-
} else {
|
|
841
|
-
this.eventListeners.set(event, [listeners, object]);
|
|
842
|
-
}
|
|
843
|
-
return this;
|
|
844
|
-
}
|
|
845
|
-
removeEventListener(event, listener, options) {
|
|
846
|
-
if (!listener) {
|
|
847
|
-
this.eventListeners.delete(event);
|
|
848
|
-
return this;
|
|
849
|
-
}
|
|
850
|
-
const listeners = this.eventListeners.get(event);
|
|
851
|
-
if (!listeners) {
|
|
852
|
-
return this;
|
|
853
|
-
}
|
|
854
|
-
if (Array.isArray(listeners)) {
|
|
855
|
-
const events = [];
|
|
856
|
-
for (let i = 0, length = listeners.length; i < length; i++) {
|
|
857
|
-
const object = listeners[i];
|
|
858
|
-
if (object.value !== listener || typeof options === "object" && options?.once && (typeof object.options === "boolean" || !object.options?.once)) {
|
|
859
|
-
events.push(object);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
if (events.length) {
|
|
863
|
-
this.eventListeners.set(event, events.length === 1 ? events[0] : events);
|
|
864
|
-
} else {
|
|
865
|
-
this.eventListeners.delete(event);
|
|
866
|
-
}
|
|
867
|
-
} else {
|
|
868
|
-
if (listeners.value === listener && (typeof options === "boolean" || !options?.once || (typeof listeners.options === "boolean" || listeners.options?.once))) {
|
|
869
|
-
this.eventListeners.delete(event);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
return this;
|
|
873
|
-
}
|
|
874
|
-
removeAllListeners() {
|
|
875
|
-
this.eventListeners.clear();
|
|
876
|
-
return this;
|
|
877
|
-
}
|
|
878
|
-
hasEventListener(event) {
|
|
879
|
-
return this.eventListeners.has(event);
|
|
880
|
-
}
|
|
881
|
-
dispatchEvent(event, arg) {
|
|
882
|
-
const listeners = this.eventListeners.get(event);
|
|
883
|
-
if (listeners) {
|
|
884
|
-
if (Array.isArray(listeners)) {
|
|
885
|
-
for (let len = listeners.length, i = 0; i < len; i++) {
|
|
886
|
-
const object = listeners[i];
|
|
887
|
-
if (typeof object.options === "object" && object.options?.once) {
|
|
888
|
-
this.off(event, object.value, object.options);
|
|
889
|
-
}
|
|
890
|
-
object.value.apply(this, [arg]);
|
|
891
|
-
}
|
|
892
|
-
} else {
|
|
893
|
-
if (typeof listeners.options === "object" && listeners.options?.once) {
|
|
894
|
-
this.off(event, listeners.value, listeners.options);
|
|
895
|
-
}
|
|
896
|
-
listeners.value.apply(this, [arg]);
|
|
897
|
-
}
|
|
898
|
-
return true;
|
|
899
|
-
} else {
|
|
900
|
-
return false;
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
on(event, listener, options) {
|
|
904
|
-
return this.addEventListener(event, listener, options);
|
|
905
|
-
}
|
|
906
|
-
once(event, listener) {
|
|
907
|
-
return this.addEventListener(event, listener, { once: true });
|
|
908
|
-
}
|
|
909
|
-
off(event, listener, options) {
|
|
910
|
-
return this.removeEventListener(event, listener, options);
|
|
911
|
-
}
|
|
912
|
-
emit(event, arg) {
|
|
913
|
-
this.dispatchEvent(event, arg);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
831
|
function background() {
|
|
918
832
|
const pathSet = new modernPath2d.Path2DSet();
|
|
919
833
|
const loader = createSVGLoader();
|
|
@@ -1626,13 +1540,17 @@ function textDecoration() {
|
|
|
1626
1540
|
});
|
|
1627
1541
|
}
|
|
1628
1542
|
|
|
1543
|
+
var __defProp$1 = Object.defineProperty;
|
|
1544
|
+
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
1545
|
+
var result = void 0 ;
|
|
1546
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
1547
|
+
if (decorator = decorators[i])
|
|
1548
|
+
result = (decorator(target, key, result) ) || result;
|
|
1549
|
+
if (result) __defProp$1(target, key, result);
|
|
1550
|
+
return result;
|
|
1551
|
+
};
|
|
1629
1552
|
const textDefaultStyle = modernIdoc.getDefaultStyle();
|
|
1630
|
-
class Text extends EventEmitter {
|
|
1631
|
-
debug;
|
|
1632
|
-
content;
|
|
1633
|
-
style;
|
|
1634
|
-
effects;
|
|
1635
|
-
measureDOM;
|
|
1553
|
+
class Text extends modernIdoc.EventEmitter {
|
|
1636
1554
|
needsUpdate = true;
|
|
1637
1555
|
computedStyle = { ...textDefaultStyle };
|
|
1638
1556
|
paragraphs = [];
|
|
@@ -1643,7 +1561,6 @@ class Text extends EventEmitter {
|
|
|
1643
1561
|
boundingBox = new modernPath2d.BoundingBox();
|
|
1644
1562
|
measurer = new Measurer();
|
|
1645
1563
|
plugins = /* @__PURE__ */ new Map();
|
|
1646
|
-
fonts;
|
|
1647
1564
|
get fontSize() {
|
|
1648
1565
|
return this.computedStyle.fontSize;
|
|
1649
1566
|
}
|
|
@@ -1660,9 +1577,9 @@ class Text extends EventEmitter {
|
|
|
1660
1577
|
set(options = {}) {
|
|
1661
1578
|
this.debug = options.debug ?? false;
|
|
1662
1579
|
this.content = modernIdoc.normalizeTextContent(options.content ?? "");
|
|
1580
|
+
this.effects = options.effects;
|
|
1663
1581
|
this.style = options.style ?? {};
|
|
1664
1582
|
this.measureDOM = options.measureDOM;
|
|
1665
|
-
this.effects = options.effects;
|
|
1666
1583
|
this.fonts = options.fonts;
|
|
1667
1584
|
this.use(background()).use(outline()).use(listStyle()).use(textDecoration()).use(highlight()).use(render());
|
|
1668
1585
|
(options.plugins ?? []).forEach((plugin) => {
|
|
@@ -1670,6 +1587,9 @@ class Text extends EventEmitter {
|
|
|
1670
1587
|
});
|
|
1671
1588
|
this.updateParagraphs();
|
|
1672
1589
|
}
|
|
1590
|
+
onUpdateProperty(key, newValue, oldValue, declaration) {
|
|
1591
|
+
this.emit("updateProperty", key, newValue, oldValue, declaration);
|
|
1592
|
+
}
|
|
1673
1593
|
use(plugin) {
|
|
1674
1594
|
this.plugins.set(plugin.name, plugin);
|
|
1675
1595
|
return this;
|
|
@@ -1820,6 +1740,24 @@ class Text extends EventEmitter {
|
|
|
1820
1740
|
return this.content.flatMap((p) => p.fragments.map((f) => f.content)).join("");
|
|
1821
1741
|
}
|
|
1822
1742
|
}
|
|
1743
|
+
__decorateClass$1([
|
|
1744
|
+
modernIdoc.property()
|
|
1745
|
+
], Text.prototype, "debug");
|
|
1746
|
+
__decorateClass$1([
|
|
1747
|
+
modernIdoc.property()
|
|
1748
|
+
], Text.prototype, "content");
|
|
1749
|
+
__decorateClass$1([
|
|
1750
|
+
modernIdoc.property()
|
|
1751
|
+
], Text.prototype, "effects");
|
|
1752
|
+
__decorateClass$1([
|
|
1753
|
+
modernIdoc.property()
|
|
1754
|
+
], Text.prototype, "style");
|
|
1755
|
+
__decorateClass$1([
|
|
1756
|
+
modernIdoc.property()
|
|
1757
|
+
], Text.prototype, "measureDOM");
|
|
1758
|
+
__decorateClass$1([
|
|
1759
|
+
modernIdoc.property()
|
|
1760
|
+
], Text.prototype, "fonts");
|
|
1823
1761
|
|
|
1824
1762
|
function measureText(options, load) {
|
|
1825
1763
|
const text = new Text(options);
|
|
@@ -1841,6 +1779,15 @@ function renderText(options, load) {
|
|
|
1841
1779
|
return text.render(options);
|
|
1842
1780
|
}
|
|
1843
1781
|
|
|
1782
|
+
var __defProp = Object.defineProperty;
|
|
1783
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
1784
|
+
var result = void 0 ;
|
|
1785
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
1786
|
+
if (decorator = decorators[i])
|
|
1787
|
+
result = (decorator(target, key, result) ) || result;
|
|
1788
|
+
if (result) __defProp(target, key, result);
|
|
1789
|
+
return result;
|
|
1790
|
+
};
|
|
1844
1791
|
function normalizeStyle(style) {
|
|
1845
1792
|
const newStyle = {};
|
|
1846
1793
|
for (const key in style) {
|
|
@@ -1850,13 +1797,14 @@ function normalizeStyle(style) {
|
|
|
1850
1797
|
}
|
|
1851
1798
|
return newStyle;
|
|
1852
1799
|
}
|
|
1853
|
-
function
|
|
1854
|
-
return
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
1800
|
+
function textContentToCharStyles(textContent) {
|
|
1801
|
+
return textContent.flatMap((p) => {
|
|
1802
|
+
const { fragments } = p;
|
|
1803
|
+
const res = fragments.flatMap((f) => {
|
|
1804
|
+
const { content, ...fStyle } = f;
|
|
1805
|
+
return Array.from(modernIdoc.normalizeCRLF(content)).map(() => ({ ...fStyle }));
|
|
1858
1806
|
});
|
|
1859
|
-
if (modernIdoc.isCRLF(modernIdoc.normalizeCRLF(
|
|
1807
|
+
if (modernIdoc.isCRLF(modernIdoc.normalizeCRLF(fragments[fragments.length - 1]?.content ?? ""))) {
|
|
1860
1808
|
return res;
|
|
1861
1809
|
}
|
|
1862
1810
|
return [...res, {}];
|
|
@@ -1876,21 +1824,26 @@ function parseHTML(html) {
|
|
|
1876
1824
|
}
|
|
1877
1825
|
class TextEditor extends HTMLElement {
|
|
1878
1826
|
static observedAttributes = [
|
|
1879
|
-
"left",
|
|
1880
|
-
"top",
|
|
1881
1827
|
"width",
|
|
1882
|
-
"height"
|
|
1883
|
-
"is-vertical"
|
|
1828
|
+
"height"
|
|
1884
1829
|
];
|
|
1885
1830
|
static register() {
|
|
1886
1831
|
customElements.define("text-editor", this);
|
|
1887
1832
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1833
|
+
_text = new Text();
|
|
1834
|
+
get text() {
|
|
1835
|
+
return this._text;
|
|
1836
|
+
}
|
|
1837
|
+
set text(value) {
|
|
1838
|
+
if (value instanceof Text) {
|
|
1839
|
+
this._text = value;
|
|
1840
|
+
} else {
|
|
1841
|
+
this._text.set(value);
|
|
1842
|
+
}
|
|
1843
|
+
this.setTextInput(this.getTextValue());
|
|
1844
|
+
this.render();
|
|
1845
|
+
}
|
|
1892
1846
|
pixelRatio = 2;
|
|
1893
|
-
text = new Text();
|
|
1894
1847
|
composition = false;
|
|
1895
1848
|
selection = [0, 0];
|
|
1896
1849
|
prevSelection = [0, 0];
|
|
@@ -1898,7 +1851,6 @@ class TextEditor extends HTMLElement {
|
|
|
1898
1851
|
$preview;
|
|
1899
1852
|
$textInput;
|
|
1900
1853
|
$cursor;
|
|
1901
|
-
$cursorInput;
|
|
1902
1854
|
get selectionMinMax() {
|
|
1903
1855
|
return {
|
|
1904
1856
|
min: Math.min(...this.selection),
|
|
@@ -1927,10 +1879,10 @@ class TextEditor extends HTMLElement {
|
|
|
1927
1879
|
const toSelectableCharacter = (c) => {
|
|
1928
1880
|
return {
|
|
1929
1881
|
color: c.computedStyle.color,
|
|
1930
|
-
left: c.
|
|
1931
|
-
top: c.
|
|
1932
|
-
width: c.
|
|
1933
|
-
height: c.
|
|
1882
|
+
left: c.lineBox.left - this.text.boundingBox.left,
|
|
1883
|
+
top: c.lineBox.top - this.text.boundingBox.top,
|
|
1884
|
+
width: c.lineBox.width,
|
|
1885
|
+
height: c.lineBox.height,
|
|
1934
1886
|
content: c.content
|
|
1935
1887
|
};
|
|
1936
1888
|
};
|
|
@@ -2001,21 +1953,17 @@ class TextEditor extends HTMLElement {
|
|
|
2001
1953
|
position: absolute;
|
|
2002
1954
|
width: 0;
|
|
2003
1955
|
height: 0;
|
|
2004
|
-
--color: 0, 0, 0;
|
|
2005
1956
|
}
|
|
2006
1957
|
|
|
2007
1958
|
.preview {
|
|
2008
1959
|
position: absolute;
|
|
2009
1960
|
left: 0;
|
|
2010
1961
|
top: 0;
|
|
2011
|
-
width: 100%;
|
|
2012
|
-
height: 100%;
|
|
2013
1962
|
--selection-color: rgba(var(--color, 0, 0, 0), 0.4);
|
|
2014
1963
|
}
|
|
2015
1964
|
|
|
2016
1965
|
.text-input {
|
|
2017
1966
|
position: absolute;
|
|
2018
|
-
z-index: -9999;
|
|
2019
1967
|
opacity: 0;
|
|
2020
1968
|
caret-color: transparent;
|
|
2021
1969
|
left: 0;
|
|
@@ -2041,48 +1989,24 @@ class TextEditor extends HTMLElement {
|
|
|
2041
1989
|
display: none;
|
|
2042
1990
|
}
|
|
2043
1991
|
}
|
|
2044
|
-
|
|
2045
|
-
.cursor-input {
|
|
2046
|
-
position: absolute;
|
|
2047
|
-
cursor: text;
|
|
2048
|
-
left: 0;
|
|
2049
|
-
top: 0;
|
|
2050
|
-
width: 100%;
|
|
2051
|
-
height: 100%;
|
|
2052
|
-
outline: 0;
|
|
2053
|
-
}
|
|
2054
1992
|
</style>
|
|
2055
1993
|
|
|
2056
1994
|
<canvas class="preview"></canvas>
|
|
2057
1995
|
|
|
2058
|
-
<textarea class="text-input"></textarea>
|
|
1996
|
+
<textarea class="text-input" autofocus></textarea>
|
|
2059
1997
|
|
|
2060
1998
|
<div class="cursor blink"></div>
|
|
2061
|
-
|
|
2062
|
-
<div
|
|
2063
|
-
class="cursor-input"
|
|
2064
|
-
autofocus
|
|
2065
|
-
contenteditable="true"
|
|
2066
|
-
></div>
|
|
2067
1999
|
`)
|
|
2068
2000
|
);
|
|
2069
2001
|
this.$preview = shadowRoot.querySelector(".preview");
|
|
2070
2002
|
this.$textInput = shadowRoot.querySelector(".text-input");
|
|
2071
2003
|
this.$cursor = shadowRoot.querySelector(".cursor");
|
|
2072
|
-
this.$cursorInput = shadowRoot.querySelector(".cursor-input");
|
|
2073
2004
|
this.$textInput.addEventListener("compositionstart", () => this.composition = true);
|
|
2074
2005
|
this.$textInput.addEventListener("compositionend", () => this.composition = false);
|
|
2075
2006
|
this.$textInput.addEventListener("keydown", this.onKeydown.bind(this));
|
|
2076
2007
|
this.$textInput.addEventListener("input", this.onInput.bind(this));
|
|
2077
2008
|
this.$textInput.addEventListener("blur", this.onBlur.bind(this));
|
|
2078
|
-
this.$
|
|
2079
|
-
this.$cursorInput.addEventListener("focus", this.onFocus.bind(this));
|
|
2080
|
-
this.$cursorInput.addEventListener("mousedown", this.onMousedown.bind(this));
|
|
2081
|
-
}
|
|
2082
|
-
update(options) {
|
|
2083
|
-
this.text.set(options);
|
|
2084
|
-
this.setTextInput(this.getTextValue());
|
|
2085
|
-
this.render();
|
|
2009
|
+
this.$textInput.addEventListener("mousedown", this.onMousedown.bind(this));
|
|
2086
2010
|
}
|
|
2087
2011
|
getTextValue() {
|
|
2088
2012
|
return modernIdoc.textContentToString(
|
|
@@ -2100,7 +2024,7 @@ class TextEditor extends HTMLElement {
|
|
|
2100
2024
|
return emoji;
|
|
2101
2025
|
});
|
|
2102
2026
|
oldString = modernIdoc.normalizeCRLF(oldString);
|
|
2103
|
-
const oldStyles =
|
|
2027
|
+
const oldStyles = textContentToCharStyles(content);
|
|
2104
2028
|
const styles = [];
|
|
2105
2029
|
let styleIndex = 0;
|
|
2106
2030
|
let oldStyleIndex = 0;
|
|
@@ -2125,14 +2049,15 @@ class TextEditor extends HTMLElement {
|
|
|
2125
2049
|
});
|
|
2126
2050
|
let charIndex = 0;
|
|
2127
2051
|
const newContents = [];
|
|
2128
|
-
modernIdoc.normalizeTextContent(newString).forEach((p) => {
|
|
2129
|
-
|
|
2052
|
+
modernIdoc.normalizeTextContent(newString).forEach((p, pI) => {
|
|
2053
|
+
const { fragments: _, ...pStyle } = content[pI] ?? {};
|
|
2054
|
+
let newParagraph = { ...pStyle, fragments: [] };
|
|
2130
2055
|
let newFragment;
|
|
2131
2056
|
p.fragments.forEach((f) => {
|
|
2132
2057
|
Array.from(f.content).forEach((char) => {
|
|
2133
2058
|
const style = styles[charIndex] ?? {};
|
|
2134
2059
|
if (newFragment) {
|
|
2135
|
-
const { content:
|
|
2060
|
+
const { content: _2, ..._style } = newFragment;
|
|
2136
2061
|
if (isEqualStyle(style, _style)) {
|
|
2137
2062
|
newFragment.content += char;
|
|
2138
2063
|
} else {
|
|
@@ -2145,7 +2070,7 @@ class TextEditor extends HTMLElement {
|
|
|
2145
2070
|
charIndex++;
|
|
2146
2071
|
});
|
|
2147
2072
|
});
|
|
2148
|
-
if (!modernIdoc.isCRLF(p.fragments[p.fragments.length - 1]
|
|
2073
|
+
if (!modernIdoc.isCRLF(p.fragments[p.fragments.length - 1]?.content ?? "")) {
|
|
2149
2074
|
charIndex++;
|
|
2150
2075
|
}
|
|
2151
2076
|
if (newFragment) {
|
|
@@ -2153,7 +2078,7 @@ class TextEditor extends HTMLElement {
|
|
|
2153
2078
|
}
|
|
2154
2079
|
if (newParagraph.fragments.length) {
|
|
2155
2080
|
newContents.push(newParagraph);
|
|
2156
|
-
newParagraph = { fragments: [] };
|
|
2081
|
+
newParagraph = { ...pStyle, fragments: [] };
|
|
2157
2082
|
}
|
|
2158
2083
|
});
|
|
2159
2084
|
return newContents;
|
|
@@ -2175,8 +2100,11 @@ class TextEditor extends HTMLElement {
|
|
|
2175
2100
|
}
|
|
2176
2101
|
_timer;
|
|
2177
2102
|
onKeydown(e) {
|
|
2103
|
+
e.stopPropagation();
|
|
2178
2104
|
switch (e.key) {
|
|
2179
|
-
|
|
2105
|
+
case "Escape":
|
|
2106
|
+
return this.$textInput.blur();
|
|
2107
|
+
}
|
|
2180
2108
|
this.updateSelection();
|
|
2181
2109
|
this.render();
|
|
2182
2110
|
setTimeout(() => {
|
|
@@ -2188,12 +2116,8 @@ class TextEditor extends HTMLElement {
|
|
|
2188
2116
|
this.render();
|
|
2189
2117
|
}, 100);
|
|
2190
2118
|
}
|
|
2191
|
-
onFocus(e) {
|
|
2192
|
-
e.preventDefault();
|
|
2193
|
-
this.$cursorInput.blur();
|
|
2194
|
-
this.$textInput?.focus();
|
|
2195
|
-
}
|
|
2196
2119
|
onBlur() {
|
|
2120
|
+
this.emit("done", this.text);
|
|
2197
2121
|
}
|
|
2198
2122
|
findNearest(options) {
|
|
2199
2123
|
const { x, y, xWeight = 1, yWeight = 1 } = options;
|
|
@@ -2257,6 +2181,9 @@ class TextEditor extends HTMLElement {
|
|
|
2257
2181
|
this.$textInput.selectionEnd = end;
|
|
2258
2182
|
}
|
|
2259
2183
|
onMousedown(e) {
|
|
2184
|
+
e.preventDefault();
|
|
2185
|
+
e.stopPropagation();
|
|
2186
|
+
this.$textInput.focus();
|
|
2260
2187
|
const index = this.findNearest({ x: e.offsetX, y: e.offsetY });
|
|
2261
2188
|
this.selection = [index, index];
|
|
2262
2189
|
this.updateDOMSelection();
|
|
@@ -2274,14 +2201,17 @@ class TextEditor extends HTMLElement {
|
|
|
2274
2201
|
document.addEventListener("mouseup", onMouseup);
|
|
2275
2202
|
}
|
|
2276
2203
|
render() {
|
|
2277
|
-
this.text.update();
|
|
2278
|
-
this.width = this.text.boundingBox.width;
|
|
2279
|
-
this.height = this.text.boundingBox.height;
|
|
2280
2204
|
const isVertical = this.text.isVertical;
|
|
2281
|
-
this.style
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2205
|
+
this.text.style = {
|
|
2206
|
+
justifyContent: "center",
|
|
2207
|
+
alignItems: "center",
|
|
2208
|
+
textAlign: "center",
|
|
2209
|
+
color: "#FFFFFFFF",
|
|
2210
|
+
...this.text.style
|
|
2211
|
+
};
|
|
2212
|
+
this.text.style.width = this.width;
|
|
2213
|
+
this.text.style.height = this.height;
|
|
2214
|
+
this.text.requestUpdate();
|
|
2285
2215
|
let ctx;
|
|
2286
2216
|
this.text.render({
|
|
2287
2217
|
pixelRatio: this.pixelRatio,
|
|
@@ -2340,19 +2270,31 @@ class TextEditor extends HTMLElement {
|
|
|
2340
2270
|
clearTimeout(this._timer);
|
|
2341
2271
|
}
|
|
2342
2272
|
this._timer = setTimeout(() => this.$cursor.classList.add("blink"), 500);
|
|
2273
|
+
this.emit("rendered", this.text);
|
|
2343
2274
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2275
|
+
requestUpdate() {
|
|
2276
|
+
this.render();
|
|
2277
|
+
}
|
|
2278
|
+
attributeChangedCallback(name, _oldValue, newValue) {
|
|
2279
|
+
this[name] = newValue;
|
|
2280
|
+
}
|
|
2281
|
+
emit(type, detail) {
|
|
2282
|
+
return this.dispatchEvent(
|
|
2283
|
+
new CustomEvent(type, {
|
|
2284
|
+
bubbles: true,
|
|
2285
|
+
cancelable: true,
|
|
2286
|
+
composed: true,
|
|
2287
|
+
detail
|
|
2288
|
+
})
|
|
2289
|
+
);
|
|
2354
2290
|
}
|
|
2355
2291
|
}
|
|
2292
|
+
__decorateClass([
|
|
2293
|
+
modernIdoc.property()
|
|
2294
|
+
], TextEditor.prototype, "width");
|
|
2295
|
+
__decorateClass([
|
|
2296
|
+
modernIdoc.property()
|
|
2297
|
+
], TextEditor.prototype, "height");
|
|
2356
2298
|
|
|
2357
2299
|
exports.Character = Character;
|
|
2358
2300
|
exports.Fragment = Fragment;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NormalizedStyle, TextContent, NormalizedTextContent, NormalizedHighlight } from 'modern-idoc';
|
|
1
|
+
import { NormalizedStyle, TextContent, EventEmitter, PropertyDeclaration, ReactiveObject, NormalizedTextContent, NormalizedHighlight } from 'modern-idoc';
|
|
2
2
|
import { BoundingBox, Path2DDrawStyle, Path2D, Vector2, VectorLike, Path2DSet, Matrix3 } from 'modern-path2d';
|
|
3
3
|
import { Fonts, SFNT } from 'modern-font';
|
|
4
4
|
|
|
@@ -114,25 +114,6 @@ interface TextOptions {
|
|
|
114
114
|
plugins?: TextPlugin[];
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
type EventListenerValue<T = any> = (ev: T) => void;
|
|
118
|
-
type EventListenerOptions = boolean | AddEventListenerOptions;
|
|
119
|
-
interface EventListener<T = any> {
|
|
120
|
-
value: EventListenerValue<T>;
|
|
121
|
-
options?: EventListenerOptions;
|
|
122
|
-
}
|
|
123
|
-
declare class EventEmitter<T extends Record<string, any> = Record<string, any>> {
|
|
124
|
-
eventListeners: Map<keyof T, EventListener<any> | EventListener<any>[]>;
|
|
125
|
-
addEventListener<K extends keyof T>(event: K, listener: EventListenerValue<T[K]>, options?: EventListenerOptions): this;
|
|
126
|
-
removeEventListener<K extends keyof T>(event: K, listener: EventListenerValue<T[K]>, options?: EventListenerOptions): this;
|
|
127
|
-
removeAllListeners(): this;
|
|
128
|
-
hasEventListener(event: string): boolean;
|
|
129
|
-
dispatchEvent<K extends keyof T>(event: K, arg: T[K]): boolean;
|
|
130
|
-
on<K extends keyof T>(event: K, listener: EventListenerValue<T[K]>, options?: EventListenerOptions): this;
|
|
131
|
-
once<K extends keyof T>(event: K, listener: EventListenerValue<T[K]>): this;
|
|
132
|
-
off<K extends keyof T>(event: K, listener: EventListenerValue<T[K]>, options?: EventListenerOptions): this;
|
|
133
|
-
emit<K extends keyof T>(event: K, arg: T[K]): void;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
117
|
interface MeasuredParagraph {
|
|
137
118
|
paragraphIndex: number;
|
|
138
119
|
left: number;
|
|
@@ -211,25 +192,32 @@ interface MeasureResult {
|
|
|
211
192
|
}
|
|
212
193
|
declare const textDefaultStyle: NormalizedStyle;
|
|
213
194
|
interface TextEventMap {
|
|
214
|
-
|
|
195
|
+
updateProperty: [
|
|
196
|
+
key: string,
|
|
197
|
+
newValue: unknown,
|
|
198
|
+
oldValue: unknown,
|
|
199
|
+
declaration: PropertyDeclaration
|
|
200
|
+
];
|
|
201
|
+
update: [{
|
|
215
202
|
text: Text$1;
|
|
216
|
-
};
|
|
217
|
-
measure: {
|
|
203
|
+
}];
|
|
204
|
+
measure: [{
|
|
218
205
|
text: Text$1;
|
|
219
206
|
result: MeasureResult;
|
|
220
|
-
};
|
|
221
|
-
render: {
|
|
207
|
+
}];
|
|
208
|
+
render: [{
|
|
222
209
|
text: Text$1;
|
|
223
210
|
view: HTMLCanvasElement;
|
|
224
211
|
pixelRatio: number;
|
|
225
|
-
};
|
|
212
|
+
}];
|
|
226
213
|
}
|
|
227
|
-
declare class Text$1 extends EventEmitter<TextEventMap> {
|
|
214
|
+
declare class Text$1 extends EventEmitter<TextEventMap> implements ReactiveObject {
|
|
228
215
|
debug: boolean;
|
|
229
216
|
content: NormalizedTextContent;
|
|
230
|
-
style: Partial<NormalizedStyle>;
|
|
231
217
|
effects?: Partial<NormalizedStyle>[];
|
|
218
|
+
style: Partial<NormalizedStyle>;
|
|
232
219
|
measureDOM?: HTMLElement;
|
|
220
|
+
fonts?: Fonts;
|
|
233
221
|
needsUpdate: boolean;
|
|
234
222
|
computedStyle: NormalizedStyle;
|
|
235
223
|
paragraphs: Paragraph[];
|
|
@@ -240,12 +228,12 @@ declare class Text$1 extends EventEmitter<TextEventMap> {
|
|
|
240
228
|
boundingBox: BoundingBox;
|
|
241
229
|
measurer: Measurer;
|
|
242
230
|
plugins: Map<string, TextPlugin>;
|
|
243
|
-
fonts?: Fonts;
|
|
244
231
|
get fontSize(): number;
|
|
245
232
|
get isVertical(): boolean;
|
|
246
233
|
get characters(): Character[];
|
|
247
234
|
constructor(options?: TextOptions);
|
|
248
235
|
set(options?: TextOptions): void;
|
|
236
|
+
onUpdateProperty(key: string, newValue: unknown, oldValue: unknown, declaration: PropertyDeclaration): void;
|
|
249
237
|
use(plugin: TextPlugin): this;
|
|
250
238
|
forEachCharacter(handle: (character: Character, ctx: {
|
|
251
239
|
paragraphIndex: number;
|
|
@@ -332,15 +320,15 @@ interface SelectableCharacter {
|
|
|
332
320
|
isLastSelected?: boolean;
|
|
333
321
|
isCrlf?: boolean;
|
|
334
322
|
}
|
|
335
|
-
declare class TextEditor extends HTMLElement {
|
|
323
|
+
declare class TextEditor extends HTMLElement implements ReactiveObject {
|
|
336
324
|
static observedAttributes: string[];
|
|
337
|
-
static register(): void;
|
|
338
|
-
left: number;
|
|
339
|
-
top: number;
|
|
340
325
|
width: number;
|
|
341
326
|
height: number;
|
|
327
|
+
static register(): void;
|
|
328
|
+
protected _text: Text$1;
|
|
329
|
+
get text(): Text$1;
|
|
330
|
+
set text(value: Text$1 | TextOptions);
|
|
342
331
|
pixelRatio: number;
|
|
343
|
-
text: Text$1;
|
|
344
332
|
composition: boolean;
|
|
345
333
|
selection: number[];
|
|
346
334
|
prevSelection: number[];
|
|
@@ -348,7 +336,6 @@ declare class TextEditor extends HTMLElement {
|
|
|
348
336
|
$preview: HTMLCanvasElement;
|
|
349
337
|
$textInput: HTMLTextAreaElement;
|
|
350
338
|
$cursor: HTMLElement;
|
|
351
|
-
$cursorInput: HTMLElement;
|
|
352
339
|
get selectionMinMax(): {
|
|
353
340
|
min: number;
|
|
354
341
|
max: number;
|
|
@@ -363,14 +350,12 @@ declare class TextEditor extends HTMLElement {
|
|
|
363
350
|
color: string;
|
|
364
351
|
};
|
|
365
352
|
constructor();
|
|
366
|
-
update(options: TextOptions): void;
|
|
367
353
|
getTextValue(): string;
|
|
368
354
|
getContentValue(content: NormalizedTextContent, newString?: string, oldString?: string): NormalizedTextContent;
|
|
369
355
|
setTextInput(newText: string): void;
|
|
370
356
|
onInput(): void;
|
|
371
357
|
protected _timer?: any;
|
|
372
358
|
onKeydown(e: KeyboardEvent): void;
|
|
373
|
-
onFocus(e: Event): void;
|
|
374
359
|
onBlur(): void;
|
|
375
360
|
findNearest(options: {
|
|
376
361
|
x: number;
|
|
@@ -382,7 +367,9 @@ declare class TextEditor extends HTMLElement {
|
|
|
382
367
|
updateDOMSelection(): void;
|
|
383
368
|
onMousedown(e: MouseEvent): void;
|
|
384
369
|
render(): void;
|
|
385
|
-
|
|
370
|
+
requestUpdate(): void;
|
|
371
|
+
attributeChangedCallback(name: string, _oldValue: any, newValue: any): void;
|
|
372
|
+
emit(type: string, detail?: any): boolean;
|
|
386
373
|
}
|
|
387
374
|
|
|
388
375
|
export { Character, Fragment, Measurer, Paragraph, Text$1 as Text, TextEditor, background, createSVGLoader, createSVGParser, definePlugin, drawPath, filterEmpty, getHighlightStyle, getTransform2D, hexToRgb, highlight, isEqualObject, isEqualValue, listStyle, measureText, outline, parseColor, parseColormap, parseValueNumber, render, renderText, setupView, textDecoration, textDefaultStyle, uploadColor, uploadColors };
|