diff --git a/CHANGELOG.md b/CHANGELOG.md index c01983fd..1844e90c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## x.y.z ### Added - +- Add support for inserting an item in a CSS list (#545) - Add a class diagram to the README (#482) - Add support for the `dvh`, `lvh` and `svh` length units (#415) - Add more tests (#449) diff --git a/src/CSSList/CSSList.php b/src/CSSList/CSSList.php index 9ce207cf..b107b6ab 100644 --- a/src/CSSList/CSSList.php +++ b/src/CSSList/CSSList.php @@ -294,6 +294,22 @@ public function splice($iOffset, $iLength = null, $mReplacement = null) array_splice($this->aContents, $iOffset, $iLength, $mReplacement); } + /** + * Inserts an item in the CSS list before its sibling. If the desired sibling cannot be found, + * the item is appended at the end. + * + * @param RuleSet|CSSList|Import|Charset $item + * @param RuleSet|CSSList|Import|Charset $sibling + */ + public function insertBefore($item, $sibling): void + { + if (in_array($sibling, $this->aContents, true)) { + $this->replace($sibling, [$item, $sibling]); + } else { + $this->append($item); + } + } + /** * Removes an item from the CSS list. * diff --git a/tests/CSSList/DocumentTest.php b/tests/CSSList/DocumentTest.php index 10f72e3e..ec84f1e2 100644 --- a/tests/CSSList/DocumentTest.php +++ b/tests/CSSList/DocumentTest.php @@ -85,4 +85,59 @@ public function setContentsReplacesContentsSetInPreviousCall(): void self::assertSame($contents2, $this->subject->getContents()); } + + /** + * @test + */ + public function insertContentBeforeInsertsContentBeforeSibbling() + { + $bogusOne = new DeclarationBlock(); + $bogusOne->setSelectors('.bogus-one'); + $bogusTwo = new DeclarationBlock(); + $bogusTwo->setSelectors('.bogus-two'); + + $item = new DeclarationBlock(); + $item->setSelectors('.item'); + + $sibling = new DeclarationBlock(); + $sibling->setSelectors('.sibling'); + + $this->subject->setContents([$bogusOne, $sibling, $bogusTwo]); + + self::assertCount(3, $this->subject->getContents()); + + $this->subject->insertBefore($item, $sibling); + + self::assertCount(4, $this->subject->getContents()); + self::assertSame([$bogusOne, $item, $sibling, $bogusTwo], $this->subject->getContents()); + } + + /** + * @test + */ + public function insertContentBeforeAppendsIfSibblingNotFound() + { + $bogusOne = new DeclarationBlock(); + $bogusOne->setSelectors('.bogus-one'); + $bogusTwo = new DeclarationBlock(); + $bogusTwo->setSelectors('.bogus-two'); + + $item = new DeclarationBlock(); + $item->setSelectors('.item'); + + $sibling = new DeclarationBlock(); + $sibling->setSelectors('.sibling'); + + $orphan = new DeclarationBlock(); + $orphan->setSelectors('.forever-alone'); + + $this->subject->setContents([$bogusOne, $sibling, $bogusTwo]); + + self::assertCount(3, $this->subject->getContents()); + + $this->subject->insertBefore($item, $orphan); + + self::assertCount(4, $this->subject->getContents()); + self::assertSame([$bogusOne, $sibling, $bogusTwo, $item], $this->subject->getContents()); + } }