@loom-io/core
Version:
A file system wrapper for Node.js and Bun
179 lines (178 loc) • 4.78 kB
JavaScript
export class TextItemList {
before;
after;
_content;
constructor(content) {
this._content = [];
this._content.push(content);
}
get content() {
return this._content[0];
}
get original() {
return this._content[this._content.length - 1];
}
get start() {
return this.content.start;
}
get end() {
return this.content.end;
}
get length() {
return this.end - this.start;
}
isReverseRead() {
return !!this.content.readReverse;
}
getLastForward() {
if (!this.isReverseRead() &&
(this.after === undefined || this.after.isReverseRead())) {
return this;
}
else if (this.isReverseRead() &&
(this.before === undefined || !this.before.isReverseRead())) {
return this.before;
}
else if (this.isReverseRead()) {
return this.before?.getLastForward();
}
else {
return this.after?.getLastForward();
}
}
getLastReverse() {
if (this.isReverseRead() &&
(this.before === undefined || !this.before.isReverseRead())) {
return this;
}
else if (!this.isReverseRead() &&
(this.after === undefined || this.after.isReverseRead())) {
return this.after;
}
else if (this.isReverseRead()) {
return this.before?.getLastReverse();
}
else {
return this.after?.getLastReverse();
}
}
isFirstItem() {
return this.before === undefined;
}
getFirstItem() {
let element = this;
while (element.before !== undefined) {
element = element.before;
}
return element;
}
isLastItem() {
return this.after === undefined;
}
getLastItem() {
let element = this;
while (element.after !== undefined) {
element = element.after;
}
return element;
}
add(item) {
let f = item.getFirstItem();
let n;
do {
n = f.next();
f.separate();
if (f.start < this.start) {
this.searchAndAddBefore(f);
}
else {
this.searchAndAddAfter(f);
}
f = n;
} while (n !== undefined);
return this;
}
separate() {
if (this.before !== undefined) {
this.before.after = this.after;
this.before = undefined;
}
if (this.after !== undefined) {
this.after.before = this.before;
this.after = undefined;
}
}
searchAndAddBefore(item) {
if (item.original.start === this.original.start &&
item.original.end === this.original.end) {
return this;
}
let cur = this;
let prev;
do {
prev = cur.prev();
if (prev === undefined) {
return cur.addBefore(item);
}
else if (item.original.start > prev.original.start &&
item.original.start < cur.original.start) {
return cur.addBefore(item);
}
cur = prev;
} while (cur.hasPrev());
return cur.addBefore(item);
}
searchAndAddAfter(item) {
if (item.original.start === this.original.start &&
item.original.end === this.original.end) {
return this;
}
let cur = this;
let next;
do {
next = cur.next();
if (next === undefined) {
return cur.addAfter(item);
}
else if (item.original.start > cur.original.start &&
item.original.start < next.original.start) {
return cur.addAfter(item);
}
cur = next;
} while (cur.hasNext());
return cur.addAfter(item);
}
addBefore(item) {
if (this.before !== undefined) {
item.before = this.before;
this.before.after = item;
}
item.after = this;
this.before = item;
return item;
}
addAfter(item) {
item.before = this;
if (this.after !== undefined) {
this.after.before = item;
item.after = this.after;
}
this.after = item;
return item;
}
hasNext() {
return this.after !== undefined;
}
next() {
return this.after;
}
hasPrev() {
return this.before !== undefined;
}
prev() {
return this.before;
}
static patch(item, data) {
item._content.unshift({ ...item.content, ...data });
}
}