@visactor/vrender-core
Version:
## Description
188 lines (178 loc) • 10.5 kB
JavaScript
"use strict";
var __rest = this && this.__rest || function(s, e) {
var t = {};
for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
var i = 0;
for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
}
return t;
};
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.EditModule = exports.findCursorIdxByConfigIndex = exports.findConfigIndexByCursorIdx = exports.getDefaultCharacterConfig = void 0;
const application_1 = require("../../application");
function getDefaultCharacterConfig(attribute) {
const {fill: fill = "black", stroke: stroke = !1, fontWeight: fontWeight = "normal", lineHeight: lineHeight, fontFamily: fontFamily = "Arial", textAlign: textAlign} = attribute;
let {fontSize: fontSize = 12} = attribute;
return isFinite(fontSize) || (fontSize = 12), {
fill: fill,
stroke: stroke,
fontSize: fontSize,
fontWeight: fontWeight,
fontFamily: fontFamily,
lineHeight: lineHeight,
textAlign: textAlign
};
}
function findConfigIndexByCursorIdx(textConfig, cursorIndex) {
if (cursorIndex < 0) return 0;
const intCursorIndex = Math.round(cursorIndex);
let tempCursorIndex = intCursorIndex, lineBreak = !1, configIdx = 0;
for (configIdx = 0; configIdx < textConfig.length && tempCursorIndex >= 0; configIdx++) {
"\n" === textConfig[configIdx].text ? (tempCursorIndex -= Number(lineBreak), lineBreak = !0) : (tempCursorIndex--,
lineBreak = !1);
}
return tempCursorIndex >= 0 ? textConfig.length : (configIdx -= 1, cursorIndex > intCursorIndex && !lineBreak && (configIdx += 1),
configIdx);
}
function findCursorIdxByConfigIndex(textConfig, configIndex) {
var _a, _b, _c;
let cursorIndex = 0;
if (configIndex < 0) return -.1;
let lastLineBreak = !1;
for (let i = 0; i <= configIndex && i < textConfig.length; i++) {
"\n" === textConfig[i].text ? (cursorIndex += Number(lastLineBreak), lastLineBreak = !0) : (cursorIndex++,
lastLineBreak = !1);
}
if (cursorIndex = Math.max(cursorIndex - 1, 0), configIndex > textConfig.length - 1) return "\n" === (null === (_a = textConfig[textConfig.length - 1]) || void 0 === _a ? void 0 : _a.text) ? cursorIndex + .9 : cursorIndex + .1;
const lineBreak = "\n" === (null === (_b = textConfig[configIndex]) || void 0 === _b ? void 0 : _b.text);
if (configIndex >= textConfig.length - 1 && lineBreak) return cursorIndex + 1 - .1;
return cursorIndex -= .1, lineBreak && "\n" !== (null === (_c = textConfig[configIndex - 1]) || void 0 === _c ? void 0 : _c.text) && (cursorIndex += .2),
cursorIndex;
}
exports.getDefaultCharacterConfig = getDefaultCharacterConfig, exports.findConfigIndexByCursorIdx = findConfigIndexByCursorIdx,
exports.findCursorIdxByConfigIndex = findCursorIdxByConfigIndex;
class EditModule {
constructor(container) {
this.handleFocusIn = () => {}, this.handleFocusOut = () => {}, this.handleKeyDown = e => {
"Delete" !== e.key && "Backspace" !== e.key || this.handleInput({
data: null,
type: "Backspace"
});
}, this.handleCompositionStart = () => {
this.isComposing = !0;
const {textConfig: textConfig = []} = this.currRt.attribute;
if (this.composingConfigIdx = this.cursorIndex < 0 ? 0 : findConfigIndexByCursorIdx(textConfig, this.cursorIndex),
this.cursorIndex < 0) {
const config = textConfig[0];
textConfig.unshift(Object.assign(Object.assign(Object.assign({
fill: "black"
}, getDefaultCharacterConfig(this.currRt.attribute)), config), {
text: ""
}));
} else {
const configIdx = this.composingConfigIdx, lastConfig = textConfig[configIdx] || textConfig[configIdx - 1];
textConfig.splice(configIdx, 0, Object.assign(Object.assign(Object.assign({
fill: "black"
}, getDefaultCharacterConfig(this.currRt.attribute)), lastConfig), {
text: ""
}));
}
}, this.handleCompositionEnd = () => {
this.isComposing = !1;
const text = this.parseCompositionStr(this.composingConfigIdx);
this.composingConfigIdx = -1, this.onChangeCbList.forEach((cb => {
cb(text, this.isComposing, this.cursorIndex, this.currRt);
}));
}, this.handleInput = ev => {
if (!this.currRt) return;
if ("historyUndo" === ev.inputType) return;
const _a = this.currRt.attribute, {textConfig: textConfig = []} = _a, rest = __rest(_a, [ "textConfig" ]);
if ("Backspace" === ev.type && !textConfig.length) return;
let str = ev.data;
this.isComposing || "Backspace" === ev.type || str || (str = "\n"), this.selectionStartCursorIdx > this.cursorIndex && ([this.cursorIndex, this.selectionStartCursorIdx] = [ this.selectionStartCursorIdx, this.cursorIndex ]);
const startIdx = findConfigIndexByCursorIdx(textConfig, this.selectionStartCursorIdx), endIdx = findConfigIndexByCursorIdx(textConfig, this.cursorIndex);
let lastConfig = textConfig[this.isComposing ? this.composingConfigIdx : Math.max(startIdx - 1, 0)];
lastConfig || (lastConfig = getDefaultCharacterConfig(rest));
let nextConfig = lastConfig;
startIdx !== endIdx && (textConfig.splice(startIdx, endIdx - startIdx), this.isComposing && (this.composingConfigIdx = startIdx));
let nextConfigIdx = startIdx;
if ("Backspace" !== ev.type || this.isComposing) this.isComposing || (nextConfig = Object.assign(Object.assign({
fill: "black"
}, lastConfig), {
text: ""
}), textConfig.splice(startIdx, 0, nextConfig), nextConfigIdx++), nextConfig.text = str,
nextConfig.isComposing = this.isComposing; else if (startIdx === endIdx) {
if (startIdx <= 0) return;
textConfig.splice(startIdx - 1, 1), nextConfigIdx = Math.max(startIdx - 1, 0);
}
this.currRt.setAttributes({
textConfig: textConfig
});
let cursorIndex = this.cursorIndex;
str && str.length > 1 && !this.isComposing ? (this.parseCompositionStr(nextConfigIdx - 1),
cursorIndex = this.cursorIndex) : (cursorIndex = findCursorIdxByConfigIndex(textConfig, nextConfigIdx),
this.isComposing ? this.cursorIndex = this.selectionStartCursorIdx : this.cursorIndex = cursorIndex),
this.isComposing ? this.onInputCbList.forEach((cb => {
cb(str, this.isComposing, cursorIndex, this.currRt);
})) : this.onChangeCbList.forEach((cb => {
cb(str, this.isComposing, cursorIndex, this.currRt);
}));
}, this.container = null != container ? container : document.body;
const textAreaDom = document.createElement("textarea");
textAreaDom.autocomplete = "off", textAreaDom.innerText = "", this.applyStyle(textAreaDom),
this.container.append(textAreaDom), this.textAreaDom = textAreaDom, this.isComposing = !1,
this.composingConfigIdx = -1, this.onInputCbList = [], this.onChangeCbList = [],
this.onFocusInList = [], this.onFocusOutList = [];
}
onInput(cb) {
this.onInputCbList.push(cb);
}
onChange(cb) {
this.onChangeCbList.push(cb);
}
onFocusIn(cb) {
this.onFocusInList.push(cb);
}
onFocusOut(cb) {
this.onFocusOutList.push(cb);
}
applyStyle(textAreaDom) {
textAreaDom.setAttribute("style", "width: 100px; height: 30px; left: 0; top: 0; position: absolute; z-index: -1; outline: none; resize: none; border: none; overflow: hidden; color: transparent; user-select: none; caret-color: transparent;background-color: transparent;"),
textAreaDom.addEventListener("input", this.handleInput), textAreaDom.addEventListener("compositionstart", this.handleCompositionStart),
textAreaDom.addEventListener("compositionend", this.handleCompositionEnd), textAreaDom.addEventListener("focusin", this.handleFocusIn),
textAreaDom.addEventListener("focusout", this.handleFocusOut), application_1.application.global.addEventListener("keydown", this.handleKeyDown);
}
parseCompositionStr(configIdx) {
var _a;
const {textConfig: textConfig = []} = this.currRt.attribute, lastConfig = null !== (_a = textConfig[configIdx]) && void 0 !== _a ? _a : {};
textConfig.splice(configIdx, 1);
const text = lastConfig.text, textList = text ? Array.from(text.toString()) : [];
for (let i = 0; i < textList.length; i++) textConfig.splice(i + configIdx, 0, Object.assign(Object.assign({
fill: "black"
}, lastConfig), {
isComposing: !1,
text: textList[i]
}));
this.currRt.setAttributes({
textConfig: textConfig
});
const nextConfigIdx = configIdx + textList.length;
return this.cursorIndex = findCursorIdxByConfigIndex(textConfig, nextConfigIdx),
text;
}
moveTo(x, y, rt, cursorIndex, selectionStartCursorIdx) {
this.textAreaDom.style.left = `${x}px`, this.textAreaDom.style.top = `${y}px`, setTimeout((() => {
this.textAreaDom.focus(), this.textAreaDom.setSelectionRange(0, 0);
})), this.currRt = rt, this.cursorIndex = cursorIndex, this.selectionStartCursorIdx = selectionStartCursorIdx;
}
release() {
this.textAreaDom.removeEventListener("input", this.handleInput), this.textAreaDom.removeEventListener("compositionstart", this.handleCompositionStart),
this.textAreaDom.removeEventListener("compositionend", this.handleCompositionEnd),
this.textAreaDom.addEventListener("focusin", this.handleFocusOut), this.textAreaDom.addEventListener("focusout", this.handleFocusOut),
application_1.application.global.removeEventListener("keydown", this.handleKeyDown);
}
}
exports.EditModule = EditModule;
//# sourceMappingURL=edit-module.js.map