diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..abcc013 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +.DS_Store +composer.lock +/vendor diff --git a/README.md b/README.md new file mode 100644 index 0000000..5a7a400 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# Inky + +A PHP Implementation of ZURB's Foundation for Email parser ([Inky](https://github.com/zurb/inky)). + +## Installation + +You can install this bundle using composer + + composer require hampe/inky + +or add the package to your `composer.json` file directly. + +## Usage and Examples + +### Basic Usage. + +```php +releaseTheKraken('html...'); +``` + +### Add Tag-Alias + +```php +addAlias('test', 'callout') + +$inky->releaseTheKraken('123'); //equal to "123" +``` + +### Add your own Custom Component Factory + +Add your own Custom Component Factory, to convert HTML-Tags. + +``` +addComponentFactory(new TestComponentFactory()); +$inky->releaseTheKraken(''); +``` + +## License +See the [LICENSE](LICENSE) file for license info (it's the MIT license). + \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..db99e20 --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "hampe/inky-parse", + "description": "PHP Implementation of ZURB's Foundation for Email parser (Inky)", + "version": "1.2.3.0", + "license": "MIT", + "authors": [ + { + "name": "Thomas Hampe", + "email": "github@hampe.co" + } + ], + "require-dev": { + "phpunit/phpunit": "4.8.*" + }, + "autoload": { + "psr-4": { + "Hampe\\Inky\\": "src/" + } + }, + "require": { + "paquettg/php-html-parser": "^1.6" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..826993b --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + tests + + + \ No newline at end of file diff --git a/src/Component/AbstractComponentFactory.php b/src/Component/AbstractComponentFactory.php new file mode 100644 index 0000000..caccb6c --- /dev/null +++ b/src/Component/AbstractComponentFactory.php @@ -0,0 +1,83 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 10.01.16 + */ + + +namespace Hampe\Inky\Component; + + +use PHPHtmlParser\Dom\HtmlNode; + +abstract class AbstractComponentFactory implements ComponentFactoryInterface +{ + + protected function copyChildren(HtmlNode $fromElement, HtmlNode $toElement) + { + $newNodeChildren = $fromElement->getChildren(); + foreach($newNodeChildren as $child) { + $toElement->addChild($child); + } + return $newNodeChildren; + } + + protected function node($tag, $attributes = array()) + { + $node = new HtmlNode($tag); + foreach($attributes as $key => $attribute) { + $node->setAttribute($key, $attribute); + } + return $node; + } + + protected function table($attributes = array()) + { + return $this->node('table', $attributes); + } + + protected function tbody($attributes = array()) + { + return $this->node('tbody', $attributes); + } + + protected function tr($attributes = array()) + { + return $this->node('tr', $attributes); + } + + protected function td($attributes = array()) + { + return $this->node('td', $attributes); + } + + protected function th($attributes = array()) + { + return $this->node('th', $attributes); + } + + protected function img($attributes = array()) + { + $node = $this->node('img', $attributes); + $node->getTag()->selfClosing(); + return $node; + } + + protected function elementHasCssClass(HtmlNode $element, $cssClass) + { + $class = $element->getAttribute('class'); + return is_string($class) && strpos($class, $cssClass) !== false; + } + + protected function addCssClass($cssClass, HtmlNode $element) + { + $element->setAttribute('class', trim($cssClass . ' ' . $element->getAttribute('class'))); + } +} \ No newline at end of file diff --git a/src/Component/BlockGridFactory.php b/src/Component/BlockGridFactory.php new file mode 100644 index 0000000..b2f6f5f --- /dev/null +++ b/src/Component/BlockGridFactory.php @@ -0,0 +1,61 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 27.02.16 + */ + + +namespace Hampe\Inky\Component; + + +use Hampe\Inky\Inky; +use PHPHtmlParser\Dom\HtmlNode; + +class BlockGridFactory extends AbstractComponentFactory +{ + const NAME = 'block-grid'; + + /** + * @return string + */ + public function getName() + { + return self::NAME; + } + + /** + * {inner} + * ------------------------------------------ + * + * {inner} + *
+ * + * @param HtmlNode $element + * @param Inky $inkyInstance + * + * @return HtmlNode + */ + public function parse(HtmlNode $element, Inky $inkyInstance) + { + $upAttribute = (string) $element->getAttribute('up'); + $table = $this->table(array('class' => trim(sprintf( + 'block-grid up-%s %s', + $upAttribute, + (string) $element->getAttribute('class') + )))); + $tr = $this->tr(); + $this->copyChildren($element, $tr); + $table->addChild($tr); + + return $table; + } + + +} \ No newline at end of file diff --git a/src/Component/ButtonFactory.php b/src/Component/ButtonFactory.php new file mode 100644 index 0000000..75989f7 --- /dev/null +++ b/src/Component/ButtonFactory.php @@ -0,0 +1,113 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 10.01.16 + */ + + +namespace Hampe\Inky\Component; + + +use Hampe\Inky\Inky; +use PHPHtmlParser\Dom\HtmlNode; + +class ButtonFactory extends AbstractComponentFactory +{ + const NAME = 'button'; + + public function getName() + { + return self::NAME; + } + + + /** + * + * ----------------------------------------------- + * + * + * + * + *
+ * + * + * + * + *
{inner}
+ *
+ * + * - OR - + * + * ', + 'to' => ' + + + + +
+ + + + +
Button
+
+ ' + ), + 'creates a button with classes' => array( + 'from' => '', + 'to' => ' + + + + +
+ + + + +
Button
+
+ ', + ), + 'creates a correct expanded button' => array( + 'from' => '', + 'to' => ' + + + + +
+ + + + +
+
Button
+
+
+ ', + ), + 'Case 1' => array( + 'from' => '', + 'to' => '
Html
' + ), + 'Case 2' => array( + 'from' => '', + 'to' => '
Html
' + ), + 'Case 4' => array( + 'from' => '', + 'to' => '

Html

' + ), + 'Case 5' => array( + 'from' => '', + 'to' => '
Html
' + ) + ); + +} diff --git a/tests/Component/CalloutFactoryTest.php b/tests/Component/CalloutFactoryTest.php new file mode 100644 index 0000000..f33c0ac --- /dev/null +++ b/tests/Component/CalloutFactoryTest.php @@ -0,0 +1,45 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 13.03.16 + */ + + +namespace Component; + + +class Test extends AbstractComponentFactoryTest { + protected $testCases = array( + 'creates a callout with correct syntax' => array( + 'from' => '', + 'to' => ' + + + + +
+ ' + ), + 'copies classes to the final HTML' => array( + 'from' => '', + 'to' => ' + + + + +
+ ' + ), + 'Case 1' => array( + 'from' => 'Html', + 'to' => '
Html
' + ) + ); +} diff --git a/tests/Component/CenterFactoryTest.php b/tests/Component/CenterFactoryTest.php new file mode 100644 index 0000000..4955dd9 --- /dev/null +++ b/tests/Component/CenterFactoryTest.php @@ -0,0 +1,46 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 13.03.16 + */ + + +namespace Component; + + +class CenterFactoryTest extends AbstractComponentFactoryTest +{ + protected $testCases = array( + 'Applies a text-center class and center alignment attribute to the first child' => array( + 'from' => ' +
+
Html
+
+ ', + 'to' => ' +
+
Html
+
+ ' + ), + 'Does not choke if center tags are nested' => array( + 'from' => ' +
+
+
+ ', + 'to' => ' +
+
+
+ ' + ) + ); +} diff --git a/tests/Component/ColumnsFactoryTest.php b/tests/Component/ColumnsFactoryTest.php new file mode 100644 index 0000000..c67ed6c --- /dev/null +++ b/tests/Component/ColumnsFactoryTest.php @@ -0,0 +1,38 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class ColumnsFactoryTest extends AbstractComponentFactoryTest +{ + + protected $testCases = array( + 'Case 1' => array( + 'from' => 'Html', + 'to' => '
Html
' + ), + 'Case 2 (no small attribute)' => array( + 'from' => 'Html', + 'to' => '
Html
' + ), + 'Case 3 (no large attribute)' => array( + 'from' => '
HtmlHtml
', + 'to' => '
Html
Html
' + ), + 'Case 4 (inside row)' => array( + 'from' => 'Html', + 'to' => '
Html
' + ), + ); + +} diff --git a/tests/Component/ContainerFactoryTest.php b/tests/Component/ContainerFactoryTest.php new file mode 100644 index 0000000..d9c37c0 --- /dev/null +++ b/tests/Component/ContainerFactoryTest.php @@ -0,0 +1,26 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class ContainerFactoryTest extends AbstractComponentFactoryTest +{ + + protected $testCases = array( + 'Case 1' => array( + 'from' => 'Html', + 'to' => '
Html
' + ) + ); + +} diff --git a/tests/Component/InkyFactoryTest.php b/tests/Component/InkyFactoryTest.php new file mode 100644 index 0000000..b90874c --- /dev/null +++ b/tests/Component/InkyFactoryTest.php @@ -0,0 +1,29 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class InkyFactoryTest extends AbstractComponentFactoryTest { + + protected $testCases = array( + 'Case 1' => array( + 'from' => '', + 'to' => '' + ), + 'Case 2' => array( + 'from' => '', + 'to' => '' + ) + ); + +} diff --git a/tests/Component/MenuFactoryTest.php b/tests/Component/MenuFactoryTest.php new file mode 100644 index 0000000..936c3ac --- /dev/null +++ b/tests/Component/MenuFactoryTest.php @@ -0,0 +1,107 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class MenuFactoryTest extends AbstractComponentFactoryTest { + + protected $testCases = array( + 'creates a menu with item tags inside' => array( + 'from' => ' + + Item + + ', + 'to' => ' + + + + + + ' + ), + 'creates a menu with classes' => array( + 'from' => '', + 'to' => ' + + + + + ' + ), + 'treats vertical menus differently' => array( + 'from' => ' + + ABC + + ', + 'to' => ' + + + + + + ' + ), + 'works without using an item tag' => array( + 'from' => ' + + Item 1 + Item 2 + + ', + 'to' => ' + + + + + + + ' + ), + + 'Case 1' => array( + 'from' => 'Html', + 'to' => 'Html' + ), + 'Case 3' => array( + 'from' => ' + + ABC + Test + + ', + 'to' => ' + + + + + + ' + ), + ); + +} diff --git a/tests/Component/MenuItemFactoryTest.php b/tests/Component/MenuItemFactoryTest.php new file mode 100644 index 0000000..383f205 --- /dev/null +++ b/tests/Component/MenuItemFactoryTest.php @@ -0,0 +1,37 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class MenuItemFactoryTest extends AbstractComponentFactoryTest { + + protected $testCases = array( + 'Case 1' => array( + 'from' => 'Html', + 'to' => 'Html' + ), + 'Case 2' => array( + 'from' => 'Html', + 'to' => '' + ), + 'Case 3' => array( + 'from' => 'HtmlHtmlHtml', + 'to' => '' + ), + 'Case 4' => array( + 'from' => 'Html', + 'to' => 'Html' + ), + ); + +} diff --git a/tests/Component/RowFactoryTest.php b/tests/Component/RowFactoryTest.php new file mode 100644 index 0000000..90d5b1d --- /dev/null +++ b/tests/Component/RowFactoryTest.php @@ -0,0 +1,25 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 28.02.16 + */ + +namespace Component; + +class RowFactoryTest extends AbstractComponentFactoryTest { + + protected $testCases = array( + 'Case 1' => array( + 'from' => 'Html', + 'to' => 'Html
' + ) + ); + +} diff --git a/tests/InkyTest.php b/tests/InkyTest.php new file mode 100644 index 0000000..252bda0 --- /dev/null +++ b/tests/InkyTest.php @@ -0,0 +1,43 @@ + + * @copyright 2013-2016 Thomas Hampe + * @date 13.03.16 + */ + + +class InkyTest extends PHPUnit_Framework_TestCase { + + public function testGridColumns() + { + $inky = new \Hampe\Inky\Inky(10); + $this->assertEquals(10, $inky->getGridColumns(), 'Inky Grid Coulmns'); + + $inky->setGridColumns(23); + $this->assertEquals(23, $inky->getGridColumns(), 'Inky Grid Columns'); + } + + public function testAlias() + { + $inky = new \Hampe\Inky\Inky(); + + $inky->addAlias('test', 'callout'); + $this->assertContains('test', $inky->getAllAliasForTagName('callout'), 'Inky Alias for Tag'); + $this->assertEquals($inky->getComponentFactory('callout'), $inky->getComponentFactory('test')); + $this->assertEquals('
Test
', $inky->releaseTheKraken('Test')); + + + $inky->removeAlias('test'); + $this->assertNotContains('test', $inky->getAllAliasForTagName('callout')); + $this->assertEquals(null, $inky->getComponentFactory('test')); + $this->assertEquals('Test', $inky->releaseTheKraken('Test')); + + } + +}