Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* `eachAttribNumber()`
* `makeAttribsString()`
* `opAttributeValue()`
* `opIterator()`: Deprecated in favor of the new `deserializeOps()` generator
function.
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
generator function.
* `newOp()`: Deprecated in favor of the new `Op` class.
Expand Down
5 changes: 2 additions & 3 deletions doc/api/hooks_server-side.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,8 @@ const Changeset = require('ep_etherpad-lite/static/js/Changeset');

exports.getLineHTMLForExport = async (hookName, context) => {
if (!context.attribLine) return;
const opIter = Changeset.opIterator(context.attribLine);
if (!opIter.hasNext()) return;
const op = opIter.next();
const [op] = Changeset.deserializeOps(context.attribLine);
if (op == null) return;
const heading = AttributeMap.fromString(op.attribs, context.apool).get('heading');
if (!heading) return;
context.lineContent = `<${heading}>${context.lineContent}</${heading}>`;
Expand Down
4 changes: 1 addition & 3 deletions src/node/db/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,10 @@ exports.restoreRevision = async (padID, rev) => {
atext.text += '\n';

const eachAttribRun = (attribs, func) => {
const attribsIter = Changeset.opIterator(attribs);
let textIndex = 0;
const newTextStart = 0;
const newTextEnd = atext.text.length;
while (attribsIter.hasNext()) {
const op = attribsIter.next();
for (const op of Changeset.deserializeOps(attribs)) {
const nextIndex = textIndex + op.chars;
if (!(nextIndex <= newTextStart || textIndex >= newTextEnd)) {
func(Math.max(newTextStart, textIndex), Math.min(newTextEnd, nextIndex), op.attribs);
Expand Down
11 changes: 2 additions & 9 deletions src/node/handler/PadMessageHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,12 +586,7 @@ const handleUserChanges = async (socket, message) => {
Changeset.checkRep(changeset);

// Validate all added 'author' attribs to be the same value as the current user
const iterator = Changeset.opIterator(Changeset.unpack(changeset).ops);
let op;

while (iterator.hasNext()) {
op = iterator.next();

for (const op of Changeset.deserializeOps(Changeset.unpack(changeset).ops)) {
// + can add text with attribs
// = can change or add attribs
// - can have attribs, but they are discarded and don't show up in the attribs -
Expand Down Expand Up @@ -741,10 +736,8 @@ const _correctMarkersInPad = (atext, apool) => {
// collect char positions of line markers (e.g. bullets) in new atext
// that aren't at the start of a line
const badMarkers = [];
const iter = Changeset.opIterator(atext.attribs);
let offset = 0;
while (iter.hasNext()) {
const op = iter.next();
for (const op of Changeset.deserializeOps(atext.attribs)) {
const attribs = AttributeMap.fromString(op.attribs, apool);
const hasMarker = AttributeManager.lineAttributes.some((a) => attribs.has(a));
if (hasMarker) {
Expand Down
5 changes: 2 additions & 3 deletions src/node/utils/ExportHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ exports._analyzeLine = (text, aline, apool) => {
let lineMarker = 0;
line.listLevel = 0;
if (aline) {
const opIter = Changeset.opIterator(aline);
if (opIter.hasNext()) {
const op = opIter.next();
const [op] = Changeset.deserializeOps(aline);
if (op != null) {
const attribs = AttributeMap.fromString(op.attribs, apool);
let listType = attribs.get('list');
if (listType) {
Expand Down
5 changes: 2 additions & 3 deletions src/node/utils/ExportHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,12 @@ const getHTMLFromAtext = async (pad, atext, authorColors) => {
return;
}

const iter = Changeset.opIterator(Changeset.subattribution(attribs, idx, idx + numChars));
const ops = Changeset.deserializeOps(Changeset.subattribution(attribs, idx, idx + numChars));
idx += numChars;

// this iterates over every op string and decides which tags to open or to close
// based on the attribs used
while (iter.hasNext()) {
const o = iter.next();
for (const o of ops) {
const usedAttribs = [];

// mark all attribs as used
Expand Down
5 changes: 2 additions & 3 deletions src/node/utils/ExportTxt.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@ const getTXTFromAtext = (pad, atext, authorColors) => {
return;
}

const iter = Changeset.opIterator(Changeset.subattribution(attribs, idx, idx + numChars));
const ops = Changeset.deserializeOps(Changeset.subattribution(attribs, idx, idx + numChars));
idx += numChars;

while (iter.hasNext()) {
const o = iter.next();
for (const o of ops) {
let propChanged = false;

for (const a of attributes.decodeAttribString(o.attribs)) {
Expand Down
4 changes: 1 addition & 3 deletions src/node/utils/ImportHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,10 @@ exports.setPadHTML = async (pad, html) => {
const builder = Changeset.builder(1);

// assemble each line into the builder
const attribsIter = Changeset.opIterator(newAttribs);
let textIndex = 0;
const newTextStart = 0;
const newTextEnd = newText.length;
while (attribsIter.hasNext()) {
const op = attribsIter.next();
for (const op of Changeset.deserializeOps(newAttribs)) {
const nextIndex = textIndex + op.chars;
if (!(nextIndex <= newTextStart || textIndex >= newTextEnd)) {
const start = Math.max(newTextStart, textIndex);
Expand Down
58 changes: 26 additions & 32 deletions src/node/utils/padDiff.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,10 @@ PadDiff.prototype._isClearAuthorship = function (changeset) {
return false;
}

// lets iterator over the operators
const iterator = Changeset.opIterator(unpacked.ops);

// get the first operator, this should be a clear operator
const clearOperator = iterator.next();
const [clearOperator, anotherOp] = Changeset.deserializeOps(unpacked.ops);

// check if there is only one operator
if (iterator.hasNext() === true) {
return false;
}
if (anotherOp != null) return false;

// check if this operator doesn't change text
if (clearOperator.opcode !== '=') {
Expand Down Expand Up @@ -212,18 +206,14 @@ PadDiff.prototype._extendChangesetWithAuthor = (changeset, author, apool) => {
// unpack
const unpacked = Changeset.unpack(changeset);

const iterator = Changeset.opIterator(unpacked.ops);
const assem = Changeset.opAssembler();

// create deleted attribs
const authorAttrib = apool.putAttrib(['author', author || '']);
const deletedAttrib = apool.putAttrib(['removed', true]);
const attribs = `*${Changeset.numToString(authorAttrib)}*${Changeset.numToString(deletedAttrib)}`;

// iteratore over the operators of the changeset
while (iterator.hasNext()) {
const operator = iterator.next();

for (const operator of Changeset.deserializeOps(unpacked.ops)) {
if (operator.opcode === '-') {
// this is a delete operator, extend it with the author
operator.attribs = attribs;
Expand Down Expand Up @@ -268,22 +258,23 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {

let curLine = 0;
let curChar = 0;
let curLineOpIter = null;
let curLineOpIterLine;
let curLineOps = null;
let curLineOpsNext = null;
let curLineOpsLine;
let curLineNextOp = new Changeset.Op('+');

const unpacked = Changeset.unpack(cs);
const csIter = Changeset.opIterator(unpacked.ops);
const builder = Changeset.builder(unpacked.newLen);

const consumeAttribRuns = (numChars, func /* (len, attribs, endsLine)*/) => {
if ((!curLineOpIter) || (curLineOpIterLine !== curLine)) {
// create curLineOpIter and advance it to curChar
curLineOpIter = Changeset.opIterator(aLinesGet(curLine));
curLineOpIterLine = curLine;
if (!curLineOps || curLineOpsLine !== curLine) {
curLineOps = Changeset.deserializeOps(aLinesGet(curLine));
curLineOpsNext = curLineOps.next();
curLineOpsLine = curLine;
let indexIntoLine = 0;
while (curLineOpIter.hasNext()) {
curLineNextOp = curLineOpIter.next();
while (!curLineOpsNext.done) {
curLineNextOp = curLineOpsNext.value;
curLineOpsNext = curLineOps.next();
if (indexIntoLine + curLineNextOp.chars >= curChar) {
curLineNextOp.chars -= (curChar - indexIntoLine);
break;
Expand All @@ -293,16 +284,22 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {
}

while (numChars > 0) {
if ((!curLineNextOp.chars) && (!curLineOpIter.hasNext())) {
if (!curLineNextOp.chars && curLineOpsNext.done) {
curLine++;
curChar = 0;
curLineOpIterLine = curLine;
curLineOpsLine = curLine;
curLineNextOp.chars = 0;
curLineOpIter = Changeset.opIterator(aLinesGet(curLine));
curLineOps = Changeset.deserializeOps(aLinesGet(curLine));
curLineOpsNext = curLineOps.next();
}

if (!curLineNextOp.chars) {
curLineNextOp = curLineOpIter.hasNext() ? curLineOpIter.next() : new Changeset.Op();
if (curLineOpsNext.done) {
curLineNextOp = new Changeset.Op();
} else {
curLineNextOp = curLineOpsNext.value;
curLineOpsNext = curLineOps.next();
}
}

const charsToUse = Math.min(numChars, curLineNextOp.chars);
Expand All @@ -314,7 +311,7 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {
curChar += charsToUse;
}

if ((!curLineNextOp.chars) && (!curLineOpIter.hasNext())) {
if (!curLineNextOp.chars && curLineOpsNext.done) {
curLine++;
curChar = 0;
}
Expand All @@ -324,7 +321,7 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {
if (L) {
curLine += L;
curChar = 0;
} else if (curLineOpIter && curLineOpIterLine === curLine) {
} else if (curLineOps && curLineOpsLine === curLine) {
consumeAttribRuns(N, () => {});
} else {
curChar += N;
Expand Down Expand Up @@ -361,10 +358,7 @@ PadDiff.prototype._createDeletionChangeset = function (cs, startAText, apool) {
};
};

// iterate over all operators of this changeset
while (csIter.hasNext()) {
const csOp = csIter.next();

for (const csOp of Changeset.deserializeOps(unpacked.ops)) {
if (csOp.opcode === '=') {
const textBank = nextText(csOp.chars);

Expand Down
24 changes: 7 additions & 17 deletions src/static/js/AttributeManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
// get `attributeName` attribute of first char of line
const aline = this.rep.alines[lineNum];
if (!aline) return '';
const opIter = Changeset.opIterator(aline);
if (!opIter.hasNext()) return '';
return AttributeMap.fromString(opIter.next().attribs, this.rep.apool).get(attributeName) || '';
const [op] = Changeset.deserializeOps(aline);
if (op == null) return '';
return AttributeMap.fromString(op.attribs, this.rep.apool).get(attributeName) || '';
},

/*
Expand All @@ -163,9 +163,8 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
// get attributes of first char of line
const aline = this.rep.alines[lineNum];
if (!aline) return [];
const opIter = Changeset.opIterator(aline);
if (!opIter.hasNext()) return [];
const op = opIter.next();
const [op] = Changeset.deserializeOps(aline);
if (op == null) return [];
return [...attributes.attribsFromString(op.attribs, this.rep.apool)];
},

Expand Down Expand Up @@ -221,13 +220,8 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
const end = selEnd[1];
let hasAttrib = true;

// Iterate over attribs on this line

const opIter = Changeset.opIterator(rep.alines[lineNum]);
let indexIntoLine = 0;

while (opIter.hasNext()) {
const op = opIter.next();
for (const op of Changeset.deserializeOps(rep.alines[lineNum])) {
const opStartInLine = indexIntoLine;
const opEndInLine = opStartInLine + op.chars;
if (!hasIt(op.attribs)) {
Expand Down Expand Up @@ -260,15 +254,11 @@ AttributeManager.prototype = _(AttributeManager.prototype).extend({
if (!aline) {
return [];
}
// iterate through all operations of a line
const opIter = Changeset.opIterator(aline);

// we need to sum up how much characters each operations take until the wanted position
let currentPointer = 0;
let currentOperation;

while (opIter.hasNext()) {
currentOperation = opIter.next();
for (const currentOperation of Changeset.deserializeOps(aline)) {
currentPointer += currentOperation.chars;
if (currentPointer <= column) continue;
return [...attributes.attribsFromString(currentOperation.attribs, this.rep.apool)];
Expand Down
Loading