@leafer-in/text-editor 1.0.1 → 1.0.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.
@@ -110,26 +110,42 @@ exports.TextEditor = class TextEditor extends editor.InnerEditor {
110
110
  onLoad() {
111
111
  const { editor } = this;
112
112
  const { config } = editor.app;
113
- this._keyEvent = config.keyEvent;
114
- config.keyEvent = false;
115
113
  const text = this.editTarget;
116
114
  text.visible = false;
115
+ this.isHTMLText = !(text instanceof core.Text);
116
+ this._keyEvent = config.keyEvent;
117
+ config.keyEvent = false;
117
118
  const div = this.editDom = document.createElement('div');
118
119
  const { style } = div;
119
120
  div.contentEditable = 'true';
120
- div.innerText = text.text;
121
121
  style.position = 'fixed';
122
122
  style.transformOrigin = 'left top';
123
123
  style.boxSizing = 'border-box';
124
- const { scaleX, scaleY } = text.worldTransform;
125
- this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
126
- const fontSize = text.fontSize * this.textScale;
127
- if (fontSize < 12)
128
- this.textScale *= 12 / fontSize;
129
- editor.app.view.appendChild(div);
124
+ if (this.isHTMLText) {
125
+ div.innerHTML = text.text;
126
+ this.textScale = 1;
127
+ }
128
+ else {
129
+ div.innerText = text.text;
130
+ const { scaleX, scaleY } = text.worldTransform;
131
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
132
+ const fontSize = text.fontSize * this.textScale;
133
+ if (fontSize < 12)
134
+ this.textScale *= 12 / fontSize;
135
+ }
136
+ const { view } = editor.app;
137
+ (this.inBody = view instanceof HTMLCanvasElement) ? document.body.appendChild(div) : view.appendChild(div);
130
138
  this.eventIds = [
131
- editor.app.on_(core.PointerEvent.DOWN, (e) => { if (e.origin.target !== div)
132
- editor.closeInnerEditor(); })
139
+ editor.app.on_(core.PointerEvent.DOWN, (e) => {
140
+ let { target } = e.origin, find;
141
+ while (target) {
142
+ if (target === div)
143
+ find = true;
144
+ target = target.parentElement;
145
+ }
146
+ if (!find)
147
+ editor.closeInnerEditor();
148
+ })
133
149
  ];
134
150
  this.onFocus = this.onFocus.bind(this);
135
151
  this.onInput = this.onInput.bind(this);
@@ -154,7 +170,8 @@ exports.TextEditor = class TextEditor extends editor.InnerEditor {
154
170
  selection.addRange(range);
155
171
  }
156
172
  onInput() {
157
- this.editTarget.text = this.editDom.innerText.replace(/\n\n/, '\n');
173
+ const { editDom } = this;
174
+ this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText.replace(/\n\n/, '\n');
158
175
  }
159
176
  onFocus() {
160
177
  this.editDom.style.outline = 'none';
@@ -166,14 +183,14 @@ exports.TextEditor = class TextEditor extends editor.InnerEditor {
166
183
  onUpdate() {
167
184
  const { editTarget: text, textScale } = this;
168
185
  const { style } = this.editDom;
169
- const { x, y } = text.app.tree.clientBounds;
186
+ const { x, y } = this.inBody ? text.app.clientBounds : text.app.tree.clientBounds;
170
187
  const { a, b, c, d, e, f } = new core.Matrix(text.worldTransform).scale(1 / textScale);
171
188
  style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
172
189
  style.left = x - window.scrollX + 'px';
173
190
  style.top = y - window.scrollY + 'px';
174
191
  style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px';
175
192
  style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px';
176
- updateStyle(this.editDom, text, this.textScale);
193
+ this.isHTMLText || updateStyle(this.editDom, text, this.textScale);
177
194
  }
178
195
  onUnload() {
179
196
  const { editTarget: text, editor, editDom: dom } = this;
@@ -1,4 +1,4 @@
1
- import { ColorConvert, PointerEvent, Matrix } from '@leafer-ui/core';
1
+ import { ColorConvert, Text, PointerEvent, Matrix } from '@leafer-ui/core';
2
2
  import { registerInnerEditor, InnerEditor } from '@leafer-in/editor';
3
3
 
4
4
  /******************************************************************************
@@ -108,26 +108,42 @@ let TextEditor = class TextEditor extends InnerEditor {
108
108
  onLoad() {
109
109
  const { editor } = this;
110
110
  const { config } = editor.app;
111
- this._keyEvent = config.keyEvent;
112
- config.keyEvent = false;
113
111
  const text = this.editTarget;
114
112
  text.visible = false;
113
+ this.isHTMLText = !(text instanceof Text);
114
+ this._keyEvent = config.keyEvent;
115
+ config.keyEvent = false;
115
116
  const div = this.editDom = document.createElement('div');
116
117
  const { style } = div;
117
118
  div.contentEditable = 'true';
118
- div.innerText = text.text;
119
119
  style.position = 'fixed';
120
120
  style.transformOrigin = 'left top';
121
121
  style.boxSizing = 'border-box';
122
- const { scaleX, scaleY } = text.worldTransform;
123
- this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
124
- const fontSize = text.fontSize * this.textScale;
125
- if (fontSize < 12)
126
- this.textScale *= 12 / fontSize;
127
- editor.app.view.appendChild(div);
122
+ if (this.isHTMLText) {
123
+ div.innerHTML = text.text;
124
+ this.textScale = 1;
125
+ }
126
+ else {
127
+ div.innerText = text.text;
128
+ const { scaleX, scaleY } = text.worldTransform;
129
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
130
+ const fontSize = text.fontSize * this.textScale;
131
+ if (fontSize < 12)
132
+ this.textScale *= 12 / fontSize;
133
+ }
134
+ const { view } = editor.app;
135
+ (this.inBody = view instanceof HTMLCanvasElement) ? document.body.appendChild(div) : view.appendChild(div);
128
136
  this.eventIds = [
129
- editor.app.on_(PointerEvent.DOWN, (e) => { if (e.origin.target !== div)
130
- editor.closeInnerEditor(); })
137
+ editor.app.on_(PointerEvent.DOWN, (e) => {
138
+ let { target } = e.origin, find;
139
+ while (target) {
140
+ if (target === div)
141
+ find = true;
142
+ target = target.parentElement;
143
+ }
144
+ if (!find)
145
+ editor.closeInnerEditor();
146
+ })
131
147
  ];
132
148
  this.onFocus = this.onFocus.bind(this);
133
149
  this.onInput = this.onInput.bind(this);
@@ -152,7 +168,8 @@ let TextEditor = class TextEditor extends InnerEditor {
152
168
  selection.addRange(range);
153
169
  }
154
170
  onInput() {
155
- this.editTarget.text = this.editDom.innerText.replace(/\n\n/, '\n');
171
+ const { editDom } = this;
172
+ this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText.replace(/\n\n/, '\n');
156
173
  }
157
174
  onFocus() {
158
175
  this.editDom.style.outline = 'none';
@@ -164,14 +181,14 @@ let TextEditor = class TextEditor extends InnerEditor {
164
181
  onUpdate() {
165
182
  const { editTarget: text, textScale } = this;
166
183
  const { style } = this.editDom;
167
- const { x, y } = text.app.tree.clientBounds;
184
+ const { x, y } = this.inBody ? text.app.clientBounds : text.app.tree.clientBounds;
168
185
  const { a, b, c, d, e, f } = new Matrix(text.worldTransform).scale(1 / textScale);
169
186
  style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
170
187
  style.left = x - window.scrollX + 'px';
171
188
  style.top = y - window.scrollY + 'px';
172
189
  style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px';
173
190
  style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px';
174
- updateStyle(this.editDom, text, this.textScale);
191
+ this.isHTMLText || updateStyle(this.editDom, text, this.textScale);
175
192
  }
176
193
  onUnload() {
177
194
  const { editTarget: text, editor, editDom: dom } = this;
@@ -1 +1 @@
1
- import{ColorConvert as e,PointerEvent as t,Matrix as n}from"@leafer-ui/core";import{registerInnerEditor as o,InnerEditor as i}from"@leafer-in/editor";"function"==typeof SuppressedError&&SuppressedError;const s={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},r={top:"flex-start",middle:"center",bottom:"flex-end"};function a(t,n,o){const{style:i}=t,{fill:a,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=n;i.fontFamily=n.fontFamily,i.fontSize=n.fontSize*o+"px",function(t,n){let o="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":o=e.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const t=n.stops[0];o=e.string("string"==typeof t?t:t.color);break;default:void 0!==n.r&&(o=e.string(n))}else o=n;t.color=o}(i,a),i.fontStyle=n.italic?"italic":"normal",i.fontWeight=n.fontWeight,i.textDecoration="delete"===p?"line-through":p,i.textTransform=s[n.textCase],i.textAlign=n.textAlign,i.display="flex",i.flexDirection="column",i.justifyContent=r[n.verticalAlign],i.lineHeight=(n.__.__lineHeight||0)*o+"px",i.letterSpacing=(n.__.__letterSpacing||0)*o+"px","none"===c?i.whiteSpace="nowrap":"break"===c&&(i.wordBreak="break-all"),i.textIndent=(n.paraIndent||0)*o+"px",i.padding=l instanceof Array?l.map((e=>e*o+"px")).join(" "):(l||0)*o+"px",i.textOverflow="show"===d?"":"hide"===d?"clip":d}let l=class extends i{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:e}=this,{config:n}=e.app;this._keyEvent=n.keyEvent,n.keyEvent=!1;const o=this.editTarget;o.visible=!1;const i=this.editDom=document.createElement("div"),{style:s}=i;i.contentEditable="true",i.innerText=o.text,s.position="fixed",s.transformOrigin="left top",s.boxSizing="border-box";const{scaleX:r,scaleY:a}=o.worldTransform;this.textScale=Math.max(Math.abs(r),Math.abs(a));const l=o.fontSize*this.textScale;l<12&&(this.textScale*=12/l),e.app.view.appendChild(i),this.eventIds=[e.app.on_(t.DOWN,(t=>{t.origin.target!==i&&e.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),i.addEventListener("focus",this.onFocus),i.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const c=window.getSelection(),d=document.createRange();if(this.config.selectAll)d.selectNodeContents(i);else{const e=i.childNodes[0];d.setStartAfter(e),d.setEndAfter(e),d.collapse(!0)}c.removeAllRanges(),c.addRange(d)}onInput(){this.editTarget.text=this.editDom.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(e){"Escape"===e.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:e,textScale:t}=this,{style:o}=this.editDom,{x:i,y:s}=e.app.tree.clientBounds,{a:r,b:l,c:c,d:d,e:p,f:h}=new n(e.worldTransform).scale(1/t);o.transform=`matrix(${r},${l},${c},${d},${p},${h})`,o.left=i-window.scrollX+"px",o.top=s-window.scrollY+"px",o.width=e.width*t+(e.__.__autoWidth?20:0)+"px",o.height=e.height*t+(e.__.__autoHeight?20:0)+"px",a(this.editDom,e,this.textScale)}onUnload(){const{editTarget:e,editor:t,editDom:n}=this;e&&(this.onInput(),e.visible=!0,t.app.config.keyEvent=this._keyEvent,t.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}};l=function(e,t,n,o){var i,s=arguments.length,r=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,n,r):i(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}([o()],l);export{l as TextEditor};
1
+ import{ColorConvert as e,Text as t,PointerEvent as n,Matrix as i}from"@leafer-ui/core";import{registerInnerEditor as o,InnerEditor as s}from"@leafer-in/editor";"function"==typeof SuppressedError&&SuppressedError;const r={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},a={top:"flex-start",middle:"center",bottom:"flex-end"};function l(t,n,i){const{style:o}=t,{fill:s,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=n;o.fontFamily=n.fontFamily,o.fontSize=n.fontSize*i+"px",function(t,n){let i="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":i=e.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const t=n.stops[0];i=e.string("string"==typeof t?t:t.color);break;default:void 0!==n.r&&(i=e.string(n))}else i=n;t.color=i}(o,s),o.fontStyle=n.italic?"italic":"normal",o.fontWeight=n.fontWeight,o.textDecoration="delete"===p?"line-through":p,o.textTransform=r[n.textCase],o.textAlign=n.textAlign,o.display="flex",o.flexDirection="column",o.justifyContent=a[n.verticalAlign],o.lineHeight=(n.__.__lineHeight||0)*i+"px",o.letterSpacing=(n.__.__letterSpacing||0)*i+"px","none"===c?o.whiteSpace="nowrap":"break"===c&&(o.wordBreak="break-all"),o.textIndent=(n.paraIndent||0)*i+"px",o.padding=l instanceof Array?l.map((e=>e*i+"px")).join(" "):(l||0)*i+"px",o.textOverflow="show"===d?"":"hide"===d?"clip":d}let c=class extends s{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:e}=this,{config:i}=e.app,o=this.editTarget;o.visible=!1,this.isHTMLText=!(o instanceof t),this._keyEvent=i.keyEvent,i.keyEvent=!1;const s=this.editDom=document.createElement("div"),{style:r}=s;if(s.contentEditable="true",r.position="fixed",r.transformOrigin="left top",r.boxSizing="border-box",this.isHTMLText)s.innerHTML=o.text,this.textScale=1;else{s.innerText=o.text;const{scaleX:e,scaleY:t}=o.worldTransform;this.textScale=Math.max(Math.abs(e),Math.abs(t));const n=o.fontSize*this.textScale;n<12&&(this.textScale*=12/n)}const{view:a}=e.app;(this.inBody=a instanceof HTMLCanvasElement)?document.body.appendChild(s):a.appendChild(s),this.eventIds=[e.app.on_(n.DOWN,(t=>{let n,{target:i}=t.origin;for(;i;)i===s&&(n=!0),i=i.parentElement;n||e.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),s.addEventListener("focus",this.onFocus),s.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const l=window.getSelection(),c=document.createRange();if(this.config.selectAll)c.selectNodeContents(s);else{const e=s.childNodes[0];c.setStartAfter(e),c.setEndAfter(e),c.collapse(!0)}l.removeAllRanges(),l.addRange(c)}onInput(){const{editDom:e}=this;this.editTarget.text=this.isHTMLText?e.innerHTML:e.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(e){"Escape"===e.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:e,textScale:t}=this,{style:n}=this.editDom,{x:o,y:s}=this.inBody?e.app.clientBounds:e.app.tree.clientBounds,{a:r,b:a,c:c,d:d,e:p,f:h}=new i(e.worldTransform).scale(1/t);n.transform=`matrix(${r},${a},${c},${d},${p},${h})`,n.left=o-window.scrollX+"px",n.top=s-window.scrollY+"px",n.width=e.width*t+(e.__.__autoWidth?20:0)+"px",n.height=e.height*t+(e.__.__autoHeight?20:0)+"px",this.isHTMLText||l(this.editDom,e,this.textScale)}onUnload(){const{editTarget:e,editor:t,editDom:n}=this;e&&(this.onInput(),e.visible=!0,t.app.config.keyEvent=this._keyEvent,t.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}};c=function(e,t,n,i){var o,s=arguments.length,r=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,i);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(r=(s<3?o(r):s>3?o(t,n,r):o(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}([o()],c);export{c as TextEditor};
@@ -109,26 +109,42 @@ this.LeaferIN.textEditor = (function (exports, core, editor) {
109
109
  onLoad() {
110
110
  const { editor } = this;
111
111
  const { config } = editor.app;
112
- this._keyEvent = config.keyEvent;
113
- config.keyEvent = false;
114
112
  const text = this.editTarget;
115
113
  text.visible = false;
114
+ this.isHTMLText = !(text instanceof core.Text);
115
+ this._keyEvent = config.keyEvent;
116
+ config.keyEvent = false;
116
117
  const div = this.editDom = document.createElement('div');
117
118
  const { style } = div;
118
119
  div.contentEditable = 'true';
119
- div.innerText = text.text;
120
120
  style.position = 'fixed';
121
121
  style.transformOrigin = 'left top';
122
122
  style.boxSizing = 'border-box';
123
- const { scaleX, scaleY } = text.worldTransform;
124
- this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
125
- const fontSize = text.fontSize * this.textScale;
126
- if (fontSize < 12)
127
- this.textScale *= 12 / fontSize;
128
- editor.app.view.appendChild(div);
123
+ if (this.isHTMLText) {
124
+ div.innerHTML = text.text;
125
+ this.textScale = 1;
126
+ }
127
+ else {
128
+ div.innerText = text.text;
129
+ const { scaleX, scaleY } = text.worldTransform;
130
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
131
+ const fontSize = text.fontSize * this.textScale;
132
+ if (fontSize < 12)
133
+ this.textScale *= 12 / fontSize;
134
+ }
135
+ const { view } = editor.app;
136
+ (this.inBody = view instanceof HTMLCanvasElement) ? document.body.appendChild(div) : view.appendChild(div);
129
137
  this.eventIds = [
130
- editor.app.on_(core.PointerEvent.DOWN, (e) => { if (e.origin.target !== div)
131
- editor.closeInnerEditor(); })
138
+ editor.app.on_(core.PointerEvent.DOWN, (e) => {
139
+ let { target } = e.origin, find;
140
+ while (target) {
141
+ if (target === div)
142
+ find = true;
143
+ target = target.parentElement;
144
+ }
145
+ if (!find)
146
+ editor.closeInnerEditor();
147
+ })
132
148
  ];
133
149
  this.onFocus = this.onFocus.bind(this);
134
150
  this.onInput = this.onInput.bind(this);
@@ -153,7 +169,8 @@ this.LeaferIN.textEditor = (function (exports, core, editor) {
153
169
  selection.addRange(range);
154
170
  }
155
171
  onInput() {
156
- this.editTarget.text = this.editDom.innerText.replace(/\n\n/, '\n');
172
+ const { editDom } = this;
173
+ this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText.replace(/\n\n/, '\n');
157
174
  }
158
175
  onFocus() {
159
176
  this.editDom.style.outline = 'none';
@@ -165,14 +182,14 @@ this.LeaferIN.textEditor = (function (exports, core, editor) {
165
182
  onUpdate() {
166
183
  const { editTarget: text, textScale } = this;
167
184
  const { style } = this.editDom;
168
- const { x, y } = text.app.tree.clientBounds;
185
+ const { x, y } = this.inBody ? text.app.clientBounds : text.app.tree.clientBounds;
169
186
  const { a, b, c, d, e, f } = new core.Matrix(text.worldTransform).scale(1 / textScale);
170
187
  style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
171
188
  style.left = x - window.scrollX + 'px';
172
189
  style.top = y - window.scrollY + 'px';
173
190
  style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px';
174
191
  style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px';
175
- updateStyle(this.editDom, text, this.textScale);
192
+ this.isHTMLText || updateStyle(this.editDom, text, this.textScale);
176
193
  }
177
194
  onUnload() {
178
195
  const { editTarget: text, editor, editDom: dom } = this;
@@ -1 +1 @@
1
- "use strict";var e=require("@leafer-ui/core"),t=require("@leafer-in/editor");"function"==typeof SuppressedError&&SuppressedError;const n={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},o={top:"flex-start",middle:"center",bottom:"flex-end"};function i(t,i,s){const{style:r}=t,{fill:a,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=i;r.fontFamily=i.fontFamily,r.fontSize=i.fontSize*s+"px",function(t,n){let o="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":o=e.ColorConvert.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const t=n.stops[0];o=e.ColorConvert.string("string"==typeof t?t:t.color);break;default:void 0!==n.r&&(o=e.ColorConvert.string(n))}else o=n;t.color=o}(r,a),r.fontStyle=i.italic?"italic":"normal",r.fontWeight=i.fontWeight,r.textDecoration="delete"===p?"line-through":p,r.textTransform=n[i.textCase],r.textAlign=i.textAlign,r.display="flex",r.flexDirection="column",r.justifyContent=o[i.verticalAlign],r.lineHeight=(i.__.__lineHeight||0)*s+"px",r.letterSpacing=(i.__.__letterSpacing||0)*s+"px","none"===c?r.whiteSpace="nowrap":"break"===c&&(r.wordBreak="break-all"),r.textIndent=(i.paraIndent||0)*s+"px",r.padding=l instanceof Array?l.map((e=>e*s+"px")).join(" "):(l||0)*s+"px",r.textOverflow="show"===d?"":"hide"===d?"clip":d}exports.TextEditor=class extends t.InnerEditor{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:t}=this,{config:n}=t.app;this._keyEvent=n.keyEvent,n.keyEvent=!1;const o=this.editTarget;o.visible=!1;const i=this.editDom=document.createElement("div"),{style:s}=i;i.contentEditable="true",i.innerText=o.text,s.position="fixed",s.transformOrigin="left top",s.boxSizing="border-box";const{scaleX:r,scaleY:a}=o.worldTransform;this.textScale=Math.max(Math.abs(r),Math.abs(a));const l=o.fontSize*this.textScale;l<12&&(this.textScale*=12/l),t.app.view.appendChild(i),this.eventIds=[t.app.on_(e.PointerEvent.DOWN,(e=>{e.origin.target!==i&&t.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),i.addEventListener("focus",this.onFocus),i.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const c=window.getSelection(),d=document.createRange();if(this.config.selectAll)d.selectNodeContents(i);else{const e=i.childNodes[0];d.setStartAfter(e),d.setEndAfter(e),d.collapse(!0)}c.removeAllRanges(),c.addRange(d)}onInput(){this.editTarget.text=this.editDom.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(e){"Escape"===e.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:t,textScale:n}=this,{style:o}=this.editDom,{x:s,y:r}=t.app.tree.clientBounds,{a:a,b:l,c:c,d:d,e:p,f:h}=new e.Matrix(t.worldTransform).scale(1/n);o.transform=`matrix(${a},${l},${c},${d},${p},${h})`,o.left=s-window.scrollX+"px",o.top=r-window.scrollY+"px",o.width=t.width*n+(t.__.__autoWidth?20:0)+"px",o.height=t.height*n+(t.__.__autoHeight?20:0)+"px",i(this.editDom,t,this.textScale)}onUnload(){const{editTarget:e,editor:t,editDom:n}=this;e&&(this.onInput(),e.visible=!0,t.app.config.keyEvent=this._keyEvent,t.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}},exports.TextEditor=function(e,t,n,o){var i,s=arguments.length,r=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,n,r):i(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}([t.registerInnerEditor()],exports.TextEditor);
1
+ "use strict";var e=require("@leafer-ui/core"),t=require("@leafer-in/editor");"function"==typeof SuppressedError&&SuppressedError;const n={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},i={top:"flex-start",middle:"center",bottom:"flex-end"};function o(t,o,s){const{style:r}=t,{fill:a,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=o;r.fontFamily=o.fontFamily,r.fontSize=o.fontSize*s+"px",function(t,n){let i="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":i=e.ColorConvert.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const t=n.stops[0];i=e.ColorConvert.string("string"==typeof t?t:t.color);break;default:void 0!==n.r&&(i=e.ColorConvert.string(n))}else i=n;t.color=i}(r,a),r.fontStyle=o.italic?"italic":"normal",r.fontWeight=o.fontWeight,r.textDecoration="delete"===p?"line-through":p,r.textTransform=n[o.textCase],r.textAlign=o.textAlign,r.display="flex",r.flexDirection="column",r.justifyContent=i[o.verticalAlign],r.lineHeight=(o.__.__lineHeight||0)*s+"px",r.letterSpacing=(o.__.__letterSpacing||0)*s+"px","none"===c?r.whiteSpace="nowrap":"break"===c&&(r.wordBreak="break-all"),r.textIndent=(o.paraIndent||0)*s+"px",r.padding=l instanceof Array?l.map((e=>e*s+"px")).join(" "):(l||0)*s+"px",r.textOverflow="show"===d?"":"hide"===d?"clip":d}exports.TextEditor=class extends t.InnerEditor{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:t}=this,{config:n}=t.app,i=this.editTarget;i.visible=!1,this.isHTMLText=!(i instanceof e.Text),this._keyEvent=n.keyEvent,n.keyEvent=!1;const o=this.editDom=document.createElement("div"),{style:s}=o;if(o.contentEditable="true",s.position="fixed",s.transformOrigin="left top",s.boxSizing="border-box",this.isHTMLText)o.innerHTML=i.text,this.textScale=1;else{o.innerText=i.text;const{scaleX:e,scaleY:t}=i.worldTransform;this.textScale=Math.max(Math.abs(e),Math.abs(t));const n=i.fontSize*this.textScale;n<12&&(this.textScale*=12/n)}const{view:r}=t.app;(this.inBody=r instanceof HTMLCanvasElement)?document.body.appendChild(o):r.appendChild(o),this.eventIds=[t.app.on_(e.PointerEvent.DOWN,(e=>{let n,{target:i}=e.origin;for(;i;)i===o&&(n=!0),i=i.parentElement;n||t.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),o.addEventListener("focus",this.onFocus),o.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const a=window.getSelection(),l=document.createRange();if(this.config.selectAll)l.selectNodeContents(o);else{const e=o.childNodes[0];l.setStartAfter(e),l.setEndAfter(e),l.collapse(!0)}a.removeAllRanges(),a.addRange(l)}onInput(){const{editDom:e}=this;this.editTarget.text=this.isHTMLText?e.innerHTML:e.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(e){"Escape"===e.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:t,textScale:n}=this,{style:i}=this.editDom,{x:s,y:r}=this.inBody?t.app.clientBounds:t.app.tree.clientBounds,{a:a,b:l,c:c,d:d,e:p,f:h}=new e.Matrix(t.worldTransform).scale(1/n);i.transform=`matrix(${a},${l},${c},${d},${p},${h})`,i.left=s-window.scrollX+"px",i.top=r-window.scrollY+"px",i.width=t.width*n+(t.__.__autoWidth?20:0)+"px",i.height=t.height*n+(t.__.__autoHeight?20:0)+"px",this.isHTMLText||o(this.editDom,t,this.textScale)}onUnload(){const{editTarget:e,editor:t,editDom:n}=this;e&&(this.onInput(),e.visible=!0,t.app.config.keyEvent=this._keyEvent,t.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}},exports.TextEditor=function(e,t,n,i){var o,s=arguments.length,r=s<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,i);else for(var a=e.length-1;a>=0;a--)(o=e[a])&&(r=(s<3?o(r):s>3?o(t,n,r):o(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}([t.registerInnerEditor()],exports.TextEditor);
@@ -1 +1 @@
1
- this.LeaferIN=this.LeaferIN||{},this.LeaferIN.textEditor=function(e,t,n){"use strict";"function"==typeof SuppressedError&&SuppressedError;const o={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},i={top:"flex-start",middle:"center",bottom:"flex-end"};function s(e,n,s){const{style:r}=e,{fill:a,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=n;r.fontFamily=n.fontFamily,r.fontSize=n.fontSize*s+"px",function(e,n){let o="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":o=t.ColorConvert.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const e=n.stops[0];o=t.ColorConvert.string("string"==typeof e?e:e.color);break;default:void 0!==n.r&&(o=t.ColorConvert.string(n))}else o=n;e.color=o}(r,a),r.fontStyle=n.italic?"italic":"normal",r.fontWeight=n.fontWeight,r.textDecoration="delete"===p?"line-through":p,r.textTransform=o[n.textCase],r.textAlign=n.textAlign,r.display="flex",r.flexDirection="column",r.justifyContent=i[n.verticalAlign],r.lineHeight=(n.__.__lineHeight||0)*s+"px",r.letterSpacing=(n.__.__letterSpacing||0)*s+"px","none"===c?r.whiteSpace="nowrap":"break"===c&&(r.wordBreak="break-all"),r.textIndent=(n.paraIndent||0)*s+"px",r.padding=l instanceof Array?l.map((e=>e*s+"px")).join(" "):(l||0)*s+"px",r.textOverflow="show"===d?"":"hide"===d?"clip":d}return e.TextEditor=class extends n.InnerEditor{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:e}=this,{config:n}=e.app;this._keyEvent=n.keyEvent,n.keyEvent=!1;const o=this.editTarget;o.visible=!1;const i=this.editDom=document.createElement("div"),{style:s}=i;i.contentEditable="true",i.innerText=o.text,s.position="fixed",s.transformOrigin="left top",s.boxSizing="border-box";const{scaleX:r,scaleY:a}=o.worldTransform;this.textScale=Math.max(Math.abs(r),Math.abs(a));const l=o.fontSize*this.textScale;l<12&&(this.textScale*=12/l),e.app.view.appendChild(i),this.eventIds=[e.app.on_(t.PointerEvent.DOWN,(t=>{t.origin.target!==i&&e.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),i.addEventListener("focus",this.onFocus),i.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const c=window.getSelection(),d=document.createRange();if(this.config.selectAll)d.selectNodeContents(i);else{const e=i.childNodes[0];d.setStartAfter(e),d.setEndAfter(e),d.collapse(!0)}c.removeAllRanges(),c.addRange(d)}onInput(){this.editTarget.text=this.editDom.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(e){"Escape"===e.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:e,textScale:n}=this,{style:o}=this.editDom,{x:i,y:r}=e.app.tree.clientBounds,{a:a,b:l,c:c,d:d,e:p,f:h}=new t.Matrix(e.worldTransform).scale(1/n);o.transform=`matrix(${a},${l},${c},${d},${p},${h})`,o.left=i-window.scrollX+"px",o.top=r-window.scrollY+"px",o.width=e.width*n+(e.__.__autoWidth?20:0)+"px",o.height=e.height*n+(e.__.__autoHeight?20:0)+"px",s(this.editDom,e,this.textScale)}onUnload(){const{editTarget:e,editor:t,editDom:n}=this;e&&(this.onInput(),e.visible=!0,t.app.config.keyEvent=this._keyEvent,t.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}},e.TextEditor=function(e,t,n,o){var i,s=arguments.length,r=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,n):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,n,o);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,n,r):i(t,n))||r);return s>3&&r&&Object.defineProperty(t,n,r),r}([n.registerInnerEditor()],e.TextEditor),e}({},LeaferUI,LeaferIN.editor);
1
+ this.LeaferIN=this.LeaferIN||{},this.LeaferIN.textEditor=function(t,e,n){"use strict";"function"==typeof SuppressedError&&SuppressedError;const i={none:"none",title:"capitalize",upper:"uppercase",lower:"lowercase","small-caps":"small-caps"},o={top:"flex-start",middle:"center",bottom:"flex-end"};function s(t,n,s){const{style:r}=t,{fill:a,padding:l,textWrap:c,textOverflow:d,textDecoration:p}=n;r.fontFamily=n.fontFamily,r.fontSize=n.fontSize*s+"px",function(t,n){let i="black";n instanceof Array&&(n=n[0]);if("object"==typeof n)switch(n.type){case"solid":i=e.ColorConvert.string(n.color);break;case"image":break;case"linear":case"radial":case"angular":const t=n.stops[0];i=e.ColorConvert.string("string"==typeof t?t:t.color);break;default:void 0!==n.r&&(i=e.ColorConvert.string(n))}else i=n;t.color=i}(r,a),r.fontStyle=n.italic?"italic":"normal",r.fontWeight=n.fontWeight,r.textDecoration="delete"===p?"line-through":p,r.textTransform=i[n.textCase],r.textAlign=n.textAlign,r.display="flex",r.flexDirection="column",r.justifyContent=o[n.verticalAlign],r.lineHeight=(n.__.__lineHeight||0)*s+"px",r.letterSpacing=(n.__.__letterSpacing||0)*s+"px","none"===c?r.whiteSpace="nowrap":"break"===c&&(r.wordBreak="break-all"),r.textIndent=(n.paraIndent||0)*s+"px",r.padding=l instanceof Array?l.map((t=>t*s+"px")).join(" "):(l||0)*s+"px",r.textOverflow="show"===d?"":"hide"===d?"clip":d}return t.TextEditor=class extends n.InnerEditor{constructor(){super(...arguments),this.config={selectAll:!0},this.eventIds=[]}get tag(){return"TextEditor"}onLoad(){const{editor:t}=this,{config:n}=t.app,i=this.editTarget;i.visible=!1,this.isHTMLText=!(i instanceof e.Text),this._keyEvent=n.keyEvent,n.keyEvent=!1;const o=this.editDom=document.createElement("div"),{style:s}=o;if(o.contentEditable="true",s.position="fixed",s.transformOrigin="left top",s.boxSizing="border-box",this.isHTMLText)o.innerHTML=i.text,this.textScale=1;else{o.innerText=i.text;const{scaleX:t,scaleY:e}=i.worldTransform;this.textScale=Math.max(Math.abs(t),Math.abs(e));const n=i.fontSize*this.textScale;n<12&&(this.textScale*=12/n)}const{view:r}=t.app;(this.inBody=r instanceof HTMLCanvasElement)?document.body.appendChild(o):r.appendChild(o),this.eventIds=[t.app.on_(e.PointerEvent.DOWN,(e=>{let n,{target:i}=e.origin;for(;i;)i===o&&(n=!0),i=i.parentElement;n||t.closeInnerEditor()}))],this.onFocus=this.onFocus.bind(this),this.onInput=this.onInput.bind(this),this.onUpdate=this.onUpdate.bind(this),this.onEscape=this.onEscape.bind(this),o.addEventListener("focus",this.onFocus),o.addEventListener("input",this.onInput),window.addEventListener("keydown",this.onEscape),window.addEventListener("scroll",this.onUpdate);const a=window.getSelection(),l=document.createRange();if(this.config.selectAll)l.selectNodeContents(o);else{const t=o.childNodes[0];l.setStartAfter(t),l.setEndAfter(t),l.collapse(!0)}a.removeAllRanges(),a.addRange(l)}onInput(){const{editDom:t}=this;this.editTarget.text=this.isHTMLText?t.innerHTML:t.innerText.replace(/\n\n/,"\n")}onFocus(){this.editDom.style.outline="none"}onEscape(t){"Escape"===t.code&&this.editor.closeInnerEditor()}onUpdate(){const{editTarget:t,textScale:n}=this,{style:i}=this.editDom,{x:o,y:r}=this.inBody?t.app.clientBounds:t.app.tree.clientBounds,{a:a,b:l,c:c,d:d,e:p,f:h}=new e.Matrix(t.worldTransform).scale(1/n);i.transform=`matrix(${a},${l},${c},${d},${p},${h})`,i.left=o-window.scrollX+"px",i.top=r-window.scrollY+"px",i.width=t.width*n+(t.__.__autoWidth?20:0)+"px",i.height=t.height*n+(t.__.__autoHeight?20:0)+"px",this.isHTMLText||s(this.editDom,t,this.textScale)}onUnload(){const{editTarget:t,editor:e,editDom:n}=this;t&&(this.onInput(),t.visible=!0,e.app.config.keyEvent=this._keyEvent,e.off_(this.eventIds),n.removeEventListener("focus",this.onFocus),n.removeEventListener("input",this.onInput),window.removeEventListener("keydown",this.onEscape),window.removeEventListener("scroll",this.onUpdate),n.remove(),this.editDom=this.eventIds=void 0)}},t.TextEditor=function(t,e,n,i){var o,s=arguments.length,r=s<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,n,i);else for(var a=t.length-1;a>=0;a--)(o=t[a])&&(r=(s<3?o(r):s>3?o(e,n,r):o(e,n))||r);return s>3&&r&&Object.defineProperty(e,n,r),r}([n.registerInnerEditor()],t.TextEditor),t}({},LeaferUI,LeaferIN.editor);
package/package.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
2
  "name": "@leafer-in/text-editor",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "@leafer-in/text-editor",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
7
+ "type": "module",
7
8
  "main": "dist/text-editor.esm.js",
9
+ "exports": {
10
+ "import": "./dist/text-editor.esm.js",
11
+ "require": "./dist/text-editor.cjs",
12
+ "types": "./types/index.d.ts"
13
+ },
14
+ "types": "types/index.d.ts",
8
15
  "unpkg": "dist/text-editor.js",
9
16
  "jsdelivr": "dist/text-editor.js",
10
- "types": "types/index.d.ts",
11
17
  "files": [
18
+ "src",
12
19
  "types",
13
20
  "dist"
14
21
  ],
@@ -27,9 +34,9 @@
27
34
  "leaferjs"
28
35
  ],
29
36
  "dependencies": {
30
- "@leafer-ui/core": "1.0.1",
31
- "@leafer-in/editor": "1.0.1",
32
- "@leafer-ui/interface": "1.0.1",
33
- "@leafer-in/interface": "1.0.1"
37
+ "@leafer-ui/core": "^1.0.3",
38
+ "@leafer-in/editor": "^1.0.3",
39
+ "@leafer-ui/interface": "^1.0.3",
40
+ "@leafer-in/interface": "^1.0.3"
34
41
  }
35
42
  }
@@ -0,0 +1,152 @@
1
+ import { IText, IEventListenerId } from '@leafer-in/interface'
2
+ import { Matrix, PointerEvent, Text } from '@leafer-ui/core'
3
+ import { InnerEditor, registerInnerEditor } from '@leafer-in/editor'
4
+ import { updateStyle } from './updateStyle'
5
+
6
+
7
+ @registerInnerEditor()
8
+ export class TextEditor extends InnerEditor {
9
+
10
+ public get tag() { return 'TextEditor' }
11
+ declare public editTarget: IText
12
+
13
+ public editDom: HTMLDivElement
14
+ public textScale: number
15
+
16
+ public config = {
17
+ selectAll: true
18
+ }
19
+
20
+ public eventIds: IEventListenerId[] = []
21
+
22
+ protected inBody: boolean
23
+ protected isHTMLText: boolean
24
+ protected _keyEvent: boolean
25
+
26
+ public onLoad(): void {
27
+ const { editor } = this
28
+ const { config } = editor.app
29
+
30
+ const text = this.editTarget
31
+ text.visible = false
32
+
33
+ this.isHTMLText = !(text instanceof Text) // HTMLText
34
+ this._keyEvent = config.keyEvent
35
+ config.keyEvent = false
36
+
37
+ const div = this.editDom = document.createElement('div')
38
+ const { style } = div
39
+ div.contentEditable = 'true'
40
+ style.position = 'fixed' // 防止文本输入到边界时产生滚动
41
+ style.transformOrigin = 'left top'
42
+ style.boxSizing = 'border-box'
43
+
44
+ if (this.isHTMLText) {
45
+
46
+ div.innerHTML = text.text
47
+ this.textScale = 1
48
+
49
+ } else {
50
+
51
+ div.innerText = text.text
52
+
53
+ const { scaleX, scaleY } = text.worldTransform
54
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY))
55
+
56
+ const fontSize = text.fontSize * this.textScale
57
+ if (fontSize < 12) this.textScale *= 12 / fontSize
58
+
59
+ }
60
+
61
+ const { view } = editor.app;
62
+ (this.inBody = view instanceof HTMLCanvasElement) ? document.body.appendChild(div) : (view as HTMLDivElement).appendChild(div)
63
+
64
+ // events
65
+
66
+ this.eventIds = [
67
+ editor.app.on_(PointerEvent.DOWN, (e: PointerEvent) => {
68
+ let { target } = e.origin, find: boolean
69
+ while (target) {
70
+ if (target === div) find = true
71
+ target = target.parentElement
72
+ }
73
+ if (!find) editor.closeInnerEditor()
74
+ })
75
+ ]
76
+
77
+ this.onFocus = this.onFocus.bind(this)
78
+ this.onInput = this.onInput.bind(this)
79
+ this.onUpdate = this.onUpdate.bind(this)
80
+ this.onEscape = this.onEscape.bind(this)
81
+
82
+ div.addEventListener("focus", this.onFocus)
83
+ div.addEventListener("input", this.onInput)
84
+ window.addEventListener('keydown', this.onEscape)
85
+ window.addEventListener('scroll', this.onUpdate)
86
+
87
+ // select
88
+
89
+ const selection = window.getSelection()
90
+ const range = document.createRange()
91
+
92
+ if (this.config.selectAll) {
93
+ range.selectNodeContents(div)
94
+ } else {
95
+ const node = div.childNodes[0]
96
+ range.setStartAfter(node)
97
+ range.setEndAfter(node)
98
+ range.collapse(true)
99
+ }
100
+
101
+ selection.removeAllRanges()
102
+ selection.addRange(range)
103
+
104
+ }
105
+
106
+ protected onInput(): void {
107
+ const { editDom } = this
108
+ this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText.replace(/\n\n/, '\n')
109
+ }
110
+
111
+ protected onFocus(): void {
112
+ this.editDom.style.outline = 'none'
113
+ }
114
+
115
+ protected onEscape(e: KeyboardEvent): void {
116
+ if (e.code === 'Escape') this.editor.closeInnerEditor()
117
+ }
118
+
119
+ public onUpdate() {
120
+ const { editTarget: text, textScale } = this
121
+ const { style } = this.editDom
122
+ const { x, y } = this.inBody ? text.app.clientBounds : text.app.tree.clientBounds
123
+ const { a, b, c, d, e, f } = new Matrix(text.worldTransform).scale(1 / textScale)
124
+
125
+ style.transform = `matrix(${a},${b},${c},${d},${e},${f})`
126
+ style.left = x - window.scrollX + 'px'
127
+ style.top = y - window.scrollY + 'px'
128
+ style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px'
129
+ style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px'
130
+ this.isHTMLText || updateStyle(this.editDom, text, this.textScale)
131
+ }
132
+
133
+ public onUnload(): void {
134
+ const { editTarget: text, editor, editDom: dom } = this
135
+ if (text) {
136
+ this.onInput()
137
+ text.visible = true
138
+
139
+ editor.app.config.keyEvent = this._keyEvent
140
+ editor.off_(this.eventIds)
141
+
142
+ dom.removeEventListener("focus", this.onFocus)
143
+ dom.removeEventListener("input", this.onInput)
144
+ window.removeEventListener('keydown', this.onEscape)
145
+ window.removeEventListener('scroll', this.onUpdate)
146
+
147
+ dom.remove()
148
+ this.editDom = this.eventIds = undefined
149
+ }
150
+ }
151
+
152
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { TextEditor } from './TextEditor'
@@ -0,0 +1,79 @@
1
+ import { ColorConvert } from '@leafer-ui/core'
2
+ import { IFill, IText, IRGB } from '@leafer-ui/interface'
3
+
4
+
5
+ export const textCaseMap = {
6
+ 'none': 'none',
7
+ 'title': 'capitalize',
8
+ 'upper': 'uppercase',
9
+ 'lower': 'lowercase',
10
+ 'small-caps': 'small-caps'
11
+ }
12
+
13
+ export const verticalAlignMap = {
14
+ 'top': 'flex-start',
15
+ 'middle': 'center',
16
+ 'bottom': 'flex-end'
17
+ }
18
+
19
+ export function updateStyle(textDom: HTMLDivElement, text: IText, textScale: number): void {
20
+ const { style } = textDom
21
+ const { fill, padding, textWrap, textOverflow, textDecoration } = text
22
+
23
+ style.fontFamily = text.fontFamily
24
+ style.fontSize = text.fontSize * textScale + 'px'
25
+ setFill(style, fill)
26
+
27
+ style.fontStyle = text.italic ? 'italic' : 'normal'
28
+ style.fontWeight = text.fontWeight as string
29
+ style.textDecoration = textDecoration === 'delete' ? 'line-through' : textDecoration
30
+ style.textTransform = textCaseMap[text.textCase]
31
+
32
+ style.textAlign = text.textAlign
33
+ style.display = 'flex'
34
+ style.flexDirection = 'column'
35
+ style.justifyContent = verticalAlignMap[text.verticalAlign]
36
+
37
+ style.lineHeight = (text.__.__lineHeight || 0) * textScale + 'px'
38
+ style.letterSpacing = (text.__.__letterSpacing || 0) * textScale + 'px'
39
+ if (textWrap === 'none') {
40
+ style.whiteSpace = 'nowrap'
41
+ } else if (textWrap === 'break') {
42
+ style.wordBreak = 'break-all'
43
+ }
44
+
45
+ style.textIndent = (text.paraIndent || 0) * textScale + 'px'
46
+ style.padding = padding instanceof Array ? padding.map(item => item * textScale + 'px').join(' ') : (padding || 0) * textScale + 'px'
47
+ style.textOverflow = textOverflow === 'show' ? '' : (textOverflow === 'hide' ? 'clip' : textOverflow)
48
+
49
+ }
50
+
51
+ function setFill(style: CSSStyleDeclaration, fill: IFill): void {
52
+ let color: string = 'black'
53
+
54
+ if (fill instanceof Array) fill = fill[0]
55
+
56
+ if (typeof fill === 'object') {
57
+
58
+ switch (fill.type) {
59
+ case 'solid':
60
+ color = ColorConvert.string(fill.color)
61
+ break
62
+ case 'image':
63
+ break
64
+ case 'linear':
65
+ case 'radial':
66
+ case 'angular':
67
+ const stop = fill.stops[0]
68
+ color = ColorConvert.string(typeof stop === 'string' ? stop : stop.color)
69
+ break
70
+ default:
71
+ if ((fill as IRGB).r !== undefined) color = ColorConvert.string(fill)
72
+ }
73
+
74
+ } else {
75
+ color = fill
76
+ }
77
+
78
+ style.color = color
79
+ }
package/types/index.d.ts CHANGED
@@ -10,6 +10,8 @@ declare class TextEditor extends InnerEditor {
10
10
  selectAll: boolean;
11
11
  };
12
12
  eventIds: IEventListenerId[];
13
+ protected inBody: boolean;
14
+ protected isHTMLText: boolean;
13
15
  protected _keyEvent: boolean;
14
16
  onLoad(): void;
15
17
  protected onInput(): void;