Files
Housekeeping-web-admin/node_modules/rich-text/lib/op.js
T
2026-06-24 09:48:54 +02:00

145 lines
3.8 KiB
JavaScript

var is = require('./is');
var lib = {
attributes: {
clone: function (attributes, keepNull) {
if (!is.object(attributes)) return {};
return Object.keys(attributes).reduce(function (memo, key) {
if (attributes[key] !== undefined && (attributes[key] !== null || keepNull)) {
memo[key] = attributes[key];
}
return memo;
}, {});
},
compose: function (a, b, keepNull) {
if (!is.object(a)) a = {};
if (!is.object(b)) b = {};
var attributes = this.clone(b, keepNull);
for (var key in a) {
if (a[key] !== undefined && b[key] === undefined) {
attributes[key] = a[key];
}
}
return Object.keys(attributes).length > 0 ? attributes : undefined;
},
diff: function(a, b) {
if (!is.object(a)) a = {};
if (!is.object(b)) b = {};
var attributes = Object.keys(a).concat(Object.keys(b)).reduce(function (attributes, key) {
if (a[key] !== b[key]) {
attributes[key] = b[key] === undefined ? null : b[key];
}
return attributes;
}, {});
return Object.keys(attributes).length > 0 ? attributes : undefined;
},
transform: function (a, b, priority) {
if (!is.object(a)) return b;
if (!is.object(b)) return undefined;
if (!priority) return b; // b simply overwrites us without priority
var attributes = Object.keys(b).reduce(function (attributes, key) {
if (a[key] === undefined) attributes[key] = b[key]; // null is a valid value
return attributes;
}, {});
return Object.keys(attributes).length > 0 ? attributes : undefined;
}
},
clone: function (op) {
var newOp = this.attributes.clone(op);
if (is.object(newOp.attributes)) {
newOp.attributes = this.attributes.clone(newOp.attributes, true);
}
return newOp;
},
iterator: function (ops) {
return new Iterator(ops);
},
length: function (op) {
if (is.number(op['delete'])) {
return op['delete'];
} else if (is.number(op.retain)) {
return op.retain;
} else {
return is.string(op.insert) ? op.insert.length : 1;
}
}
};
function Iterator(ops) {
this.ops = ops;
this.index = 0;
this.offset = 0;
};
Iterator.prototype.hasNext = function () {
return this.peekLength() < Infinity;
};
Iterator.prototype.next = function (length) {
if (!length) length = Infinity;
var nextOp = this.ops[this.index];
if (nextOp) {
var offset = this.offset;
var opLength = lib.length(nextOp)
if (length >= opLength - offset) {
length = opLength - offset;
this.index += 1;
this.offset = 0;
} else {
this.offset += length;
}
if (is.number(nextOp['delete'])) {
return { 'delete': length };
} else {
var retOp = {};
if (nextOp.attributes) {
retOp.attributes = nextOp.attributes;
}
if (is.number(nextOp.retain)) {
retOp.retain = length;
} else if (is.string(nextOp.insert)) {
retOp.insert = nextOp.insert.substr(offset, length);
} else {
// offset should === 0, length should === 1
retOp.insert = nextOp.insert;
}
return retOp;
}
} else {
return { retain: Infinity };
}
};
Iterator.prototype.peekLength = function () {
if (this.ops[this.index]) {
// Should never return 0 if our index is being managed correctly
return lib.length(this.ops[this.index]) - this.offset;
} else {
return Infinity;
}
};
Iterator.prototype.peekType = function () {
if (this.ops[this.index]) {
if (is.number(this.ops[this.index]['delete'])) {
return 'delete';
} else if (is.number(this.ops[this.index].retain)) {
return 'retain';
} else {
return 'insert';
}
}
return 'retain';
};
module.exports = lib;