web-ui-pack
Version:
Web package with UI elements
141 lines (140 loc) • 4.44 kB
JavaScript
import WUPBaseElement from "../baseElement";
import { WUPcssScrollSmall } from "../styles";
let isFirst = true;
export default class WUPTextareaInput extends HTMLElement {
#ctr = this.constructor;
static $use() {
}
static get $style() {
return `:host {
display: inline-block; ${""}
cursor: text;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: break-word;
overflow: auto;
margin: 0; padding: 0;
}
${WUPcssScrollSmall(":host")}`;
}
constructor() {
super();
if (isFirst) {
WUPBaseElement.$refStyle.append(this.#ctr.$style.replace(/:host/g, `${this.tagName}`));
isFirst = false;
}
}
$options = {};
#isInit = true;
connectedCallback() {
if (this.#isInit) {
this.setAttribute("contenteditable", "true");
this.setAttribute("role", "textbox");
this.setAttribute("aria-multiline", "true");
this.#isInit = false;
this.oninput = () => {
this._cached = undefined;
};
}
}
select() {
const range = document.createRange();
range.selectNodeContents(this);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
get readOnly() {
return this.hasAttribute("aria-readonly");
}
set readOnly(v) {
WUPBaseElement.prototype.setAttr.call(this, "aria-readonly", v);
}
_cached;
get value() {
if (this._cached == null) {
this._cached = this.innerHTML
.replace(/<div><br><\/div>/g, "\n")
.replace(/<br>|<div>/g, "\n")
.replace(/<\/div>/g, "")
.replace(/^ /, "");
}
return this._cached;
}
set value(v) {
this._cached = undefined;
this.innerHTML = v;
}
setSelectionRange(start, end) {
this.selection = { start: start || 0, end: end || 0 };
}
get selectionStart() {
return this.selection?.start ?? null;
}
set selectionStart(v) {
this.selection = { start: v || 0, end: this.selection?.end };
}
get selectionEnd() {
return this.selection?.end ?? null;
}
set selectionEnd(v) {
this.selection = { start: this.selection?.start, end: v || 0 };
}
get selection() {
if (document.activeElement !== this) {
return null;
}
const sel = window.getSelection();
if (!sel || sel.rangeCount < 1) {
return null;
}
const range = sel.getRangeAt(0);
const pre = range.cloneRange();
pre.selectNodeContents(this);
pre.setEnd(range.startContainer, range.startOffset);
const start = pre.toString().length;
return {
start,
end: start + range.toString().length,
};
}
set selection(sel) {
if (document.activeElement !== this) {
return;
}
let charIndex = 0;
const range = document.createRange();
range.setStart(this, 0);
range.collapse(true);
const nodeStack = [this];
let node;
let foundStart = false;
let stop = false;
if (sel) {
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType === Node.TEXT_NODE) {
const nextCharIndex = charIndex + node.length;
if (!foundStart && sel.start >= charIndex && sel.start <= nextCharIndex) {
range.setStart(node, sel.start - charIndex);
foundStart = true;
}
if (foundStart && sel.end >= charIndex && sel.end <= nextCharIndex) {
range.setEnd(node, sel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
}
else {
let i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
}
const s = window.getSelection();
s.removeAllRanges();
s.addRange(range);
}
}
customElements.define("wup-areainput", WUPTextareaInput);