public function push(OperationInterface $newOperation) { $lastOperation = ($index = count($this->operations)) > 0 ? $this->operations[$index - 1] : null; if ($lastOperation instanceof OperationInterface) { if ($lastOperation->getType() === OperationInterface::TYPE_DELETE && $newOperation->getType() === OperationInterface::TYPE_DELETE) { $this->operations->set($index - 1, new DeleteOperation($lastOperation->getValue() + $newOperation->getValue())); return $this; } if ($lastOperation->getType() === OperationInterface::TYPE_DELETE && $newOperation->getType() === OperationInterface::TYPE_INSERT) { $index -= 1; if (!isset($this->operations[$index - 1])) { $this->operations->unshift($newOperation); return $this; } $lastOperation = $this->operations[$index - 1]; } if ($lastOperation->getAttributes() === $newOperation->getAttributes()) { if ($newOperation->getType() === OperationInterface::TYPE_INSERT && is_string($newOperation->getValue()) && $lastOperation->getType() === OperationInterface::TYPE_INSERT && is_string($lastOperation->getValue())) { $this->operations[$index - 1] = new InsertOperation($lastOperation->getValue() . $newOperation->getValue(), $newOperation->getAttributes()); return $this; } elseif ($newOperation->getType() === OperationInterface::TYPE_RETAIN && $lastOperation->getType() === OperationInterface::TYPE_RETAIN) { $this->operations[$index - 1] = new RetainOperation($lastOperation->getValue() + $newOperation->getValue(), $newOperation->getAttributes()); return $this; } } } if ($index === count($this->operations)) { $this->operations->add($newOperation); } else { $this->operations->splice($index, 0, $newOperation); } return $this; }
private function calculateLength(OperationInterface $operation) { if ($operation->getType() === OperationInterface::TYPE_DELETE || $operation->getType() === OperationInterface::TYPE_RETAIN) { return $operation->getValue(); } return $operation->getType() == OperationInterface::TYPE_INSERT && is_string($operation->getValue()) ? mb_strlen($operation->getValue()) : 1; }