From 08cf2d3640a3b2d8f82ac18f11781c7b7878d868 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Wed, 8 Sep 2021 18:21:37 +0100 Subject: [PATCH] v2 (#229) * remove all obsolete classes * upgrade dependencies * feature: DataBinder::bindValue() * tweak: update exception messages * tweak: remove unused imports * refactor: share functionality for setting bind property * refactor: simplify functionality * refactor: rename to DocumentBinder * tweak: rename test function names * refactor: simplify nested foreach * docs: update features * tweak: import fqn * refactor: remove ott checks for invalid properties * feature: bindData * feature: DocumentBinder::bindData() toggles DOMTokenList values * feature: DocumentBinder::bindData() toggles boolean values * feature: DocumentBinder::bindData() toggles boolean values with inverse logic from ! char * feature: binding tabular data to a table element * wip: table data normalisation * feature: normalise table data * feature: implement "double header" table data * test: exception if indexed array passed to bindData * test: bindData with stdClass object * test: bindKeyValue with incorrect table data * test: bindKeyValue with non-iterable double header table data * tweak: change data type to int in example * test: bindKeyValue throw error when tableData is assoc without iterable cols * test: bindKeyValue throw error when binding tableData with no table in html * wip: add todos to get bindTable to 100% * test: various table tests to ensure table data is normalised correctly * test: bindTable with header keys in the HTML * tweak: remove unused code * refactor: extract table binding into separate class * test: bindKeyValue with table data * tidy: remove unused imports * tidy: more accurate test names * refactor: extract element-specific binding to ElementBinder * feature: ListBinder basic list bound to document * feature: ListBinder binds text from values * feature: ListBinder binds templates by name * test: better working with empty lists * feature: binding an empty list will clear the innerHTML of the template's parent * test: binding a table to the document, rather than a specific element * feature: bind list of key-value-pair arrays * feature: bind list of key-value-pair objects * feature: bind list of key-value-pair instance objects * feature: Bind attribute used to mark methods/properties as dom-bindable * feature: get a template element by its document position * feature: throw exception if matching template is not found * feature: get template element by template name * feature: throw exceptions when names are not set correctly * feature: bind text placeholder * test: bind text placeholder's context does not leak * feature: remove filtering feature from HTML * feature: placeholders within attributes * tweak: more appropriate naming * improvement: binding nested elements resolve their template parents properly * feature: nested lists with implicit keys * refactor: update bind model - extract placeholder binding to separate classes * feature: complete refactor of PlaceholderBinder * test: DocumentBinder::bindList() * test: HTMLAttributeBinder::bind() with Document context * tweak: rename context to element when not performing a child search * test: ListBinder::isKVP() * chore: remove unused function * chore: remove obsolete conditional * test: ensure template names can't start with a forward slash * chore: work through PHPStan's issues * test: add a real-world test for todo items * test: ensure template's siblings are not also templates * feature: parse ini data within comments * tweak: document type of array * feature: expand custom elements * feature: expand custom elements recursively * feature: expand partials * test: harden test cases * wip: recursive partial expansion * feature: recursive partial expansion * feature: recursive partials import deepest title * chore: update deps * chore: update deps * phpstan: fix generics issue * remove unused test (from v1) * build: upgrade deps --- README.md | 78 +- composer.json | 12 +- composer.lock | 332 ++++++-- example/01-example-groceries.html | 6 - example/01-example-groceries.php | 20 - example/_component/shopping-list.html | 3 - src/Attr.php | 22 - src/Bind.php | 12 + src/BindDataMapper.php | 15 - src/BindObject.php | 15 - src/Bindable.php | 588 ------------- src/BoundAttributeDoesNotExistException.php | 4 - src/BoundDataNotSetException.php | 4 - src/CharacterData.php | 8 - src/ChildNode.php | 7 - src/Comment.php | 6 - src/CommentIni.php | 75 ++ ...entIniInvalidDocumentLocationException.php | 4 + src/CommentIniSyntaxErrorException.php | 4 + src/ComponentExpander.php | 43 + src/DataKeyMatch.php | 49 -- src/Document.php | 42 - src/DocumentBinder.php | 122 +++ src/DocumentFragment.php | 60 -- src/DocumentType.php | 8 - src/DomTemplateException.php | 4 +- src/Element.php | 48 -- src/ElementBinder.php | 108 +++ src/HTMLAttributeBinder.php | 233 +++++ src/HTMLAttributeCollection.php | 14 + src/HTMLCollection.php | 10 - src/HTMLDocument.php | 248 ------ src/IncompatibleBindDataException.php | 4 +- src/IncorrectTableDataFormat.php | 4 + src/InvalidBindProperty.php | 4 - src/InvalidBindPropertyException.php | 5 + src/InvalidTemplateElementNameException.php | 4 + src/ListBinder.php | 152 ++++ src/ModularContent.php | 27 + ...dularContentDirectoryNotFoundException.php | 4 + src/ModularContentExpander.php | 15 + src/ModularContentFileNotFoundException.php | 4 + src/NamelessTemplateSpecificityException.php | 4 - src/Node.php | 23 - src/NodeList.php | 11 - src/NodePathCalculator.php | 22 + src/NonDocumentTypeChildNode.php | 12 - src/ParentNode.php | 30 - src/PartialExpander.php | 65 ++ src/PlaceholderBinder.php | 51 ++ src/PlaceholderText.php | 46 + src/StringMap.php | 6 - src/TableBinder.php | 179 ++++ ...TableElementNotFoundInContextException.php | 4 + src/TemplateCollection.php | 91 ++ src/TemplateComponentNotFoundException.php | 4 - src/TemplateElement.php | 96 +++ src/TemplateElementNotFoundFoundException.php | 4 - ...plateElementNotFoundInContextException.php | 4 + src/TemplateHasNoParentException.php | 4 - src/TemplateParent.php | 248 ------ src/Text.php | 6 - src/TokenList.php | 6 - src/UnbindableObjectException.php | 4 - test/phpunit/BindDataGetterTest.php | 24 - test/phpunit/BindableTest.php | 795 ------------------ test/phpunit/CommentIniTest.php | 46 + test/phpunit/ComponentExpanderTest.php | 49 ++ test/phpunit/DocumentBinderTest.php | 378 +++++++++ test/phpunit/DocumentTest.php | 20 - test/phpunit/HTMLAttributeBinderTest.php | 15 + test/phpunit/HTMLDocumentTest.php | 21 - .../Helper/BindDataGetter/TodoItem.php | 37 - test/phpunit/Helper/Helper.php | 770 ----------------- test/phpunit/Helper/TodoItemExampleObject.php | 12 - test/phpunit/Helper/TodoListExampleObject.php | 45 - test/phpunit/ListBinderTest.php | 492 +++++++++++ test/phpunit/ModularContentTest.php | 66 ++ test/phpunit/ModularContentTestCase.php | 44 + test/phpunit/PartialExpanderTest.php | 93 ++ test/phpunit/PlaceholderBinderTest.php | 49 ++ test/phpunit/TableBinderTest.php | 376 +++++++++ test/phpunit/TemplateCollectionTest.php | 118 +++ test/phpunit/TemplateElementTest.php | 20 + test/phpunit/TemplateParentTest.php | 490 ----------- test/phpunit/TestCase.php | 23 - test/phpunit/TestData.php | 97 +++ .../TestFactory/DocumentTestFactory.php | 499 +++++++++++ 88 files changed, 4046 insertions(+), 3880 deletions(-) delete mode 100644 example/01-example-groceries.html delete mode 100644 example/01-example-groceries.php delete mode 100644 example/_component/shopping-list.html delete mode 100644 src/Attr.php create mode 100644 src/Bind.php delete mode 100644 src/BindDataMapper.php delete mode 100644 src/BindObject.php delete mode 100644 src/Bindable.php delete mode 100644 src/BoundAttributeDoesNotExistException.php delete mode 100644 src/BoundDataNotSetException.php delete mode 100644 src/CharacterData.php delete mode 100644 src/ChildNode.php delete mode 100644 src/Comment.php create mode 100644 src/CommentIni.php create mode 100644 src/CommentIniInvalidDocumentLocationException.php create mode 100644 src/CommentIniSyntaxErrorException.php create mode 100644 src/ComponentExpander.php delete mode 100644 src/DataKeyMatch.php delete mode 100644 src/Document.php create mode 100644 src/DocumentBinder.php delete mode 100644 src/DocumentFragment.php delete mode 100644 src/DocumentType.php delete mode 100644 src/Element.php create mode 100644 src/ElementBinder.php create mode 100644 src/HTMLAttributeBinder.php create mode 100644 src/HTMLAttributeCollection.php delete mode 100644 src/HTMLCollection.php delete mode 100644 src/HTMLDocument.php create mode 100644 src/IncorrectTableDataFormat.php delete mode 100644 src/InvalidBindProperty.php create mode 100644 src/InvalidBindPropertyException.php create mode 100644 src/InvalidTemplateElementNameException.php create mode 100644 src/ListBinder.php create mode 100644 src/ModularContent.php create mode 100644 src/ModularContentDirectoryNotFoundException.php create mode 100644 src/ModularContentExpander.php create mode 100644 src/ModularContentFileNotFoundException.php delete mode 100644 src/NamelessTemplateSpecificityException.php delete mode 100644 src/Node.php delete mode 100644 src/NodeList.php create mode 100644 src/NodePathCalculator.php delete mode 100644 src/NonDocumentTypeChildNode.php delete mode 100644 src/ParentNode.php create mode 100644 src/PartialExpander.php create mode 100644 src/PlaceholderBinder.php create mode 100644 src/PlaceholderText.php delete mode 100644 src/StringMap.php create mode 100644 src/TableBinder.php create mode 100644 src/TableElementNotFoundInContextException.php create mode 100644 src/TemplateCollection.php delete mode 100644 src/TemplateComponentNotFoundException.php create mode 100644 src/TemplateElement.php delete mode 100644 src/TemplateElementNotFoundFoundException.php create mode 100644 src/TemplateElementNotFoundInContextException.php delete mode 100644 src/TemplateHasNoParentException.php delete mode 100644 src/TemplateParent.php delete mode 100644 src/Text.php delete mode 100644 src/TokenList.php delete mode 100644 src/UnbindableObjectException.php delete mode 100644 test/phpunit/BindDataGetterTest.php delete mode 100644 test/phpunit/BindableTest.php create mode 100644 test/phpunit/CommentIniTest.php create mode 100644 test/phpunit/ComponentExpanderTest.php create mode 100644 test/phpunit/DocumentBinderTest.php delete mode 100644 test/phpunit/DocumentTest.php create mode 100644 test/phpunit/HTMLAttributeBinderTest.php delete mode 100644 test/phpunit/HTMLDocumentTest.php delete mode 100644 test/phpunit/Helper/BindDataGetter/TodoItem.php delete mode 100644 test/phpunit/Helper/Helper.php delete mode 100644 test/phpunit/Helper/TodoItemExampleObject.php delete mode 100644 test/phpunit/Helper/TodoListExampleObject.php create mode 100644 test/phpunit/ListBinderTest.php create mode 100644 test/phpunit/ModularContentTest.php create mode 100644 test/phpunit/ModularContentTestCase.php create mode 100644 test/phpunit/PartialExpanderTest.php create mode 100644 test/phpunit/PlaceholderBinderTest.php create mode 100644 test/phpunit/TableBinderTest.php create mode 100644 test/phpunit/TemplateCollectionTest.php create mode 100644 test/phpunit/TemplateElementTest.php delete mode 100644 test/phpunit/TemplateParentTest.php delete mode 100644 test/phpunit/TestCase.php create mode 100644 test/phpunit/TestData.php create mode 100644 test/phpunit/TestFactory/DocumentTestFactory.php diff --git a/README.md b/README.md index 2afe39d..1def6a2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bind dynamic data to reusable HTML components. -Built on top of [PHP.Gt/Dom][dom], this project provides simple view templating and dynamic data binding. +Built on top of [PHP.Gt/Dom][dom], this project provides dynamic data binding to DOM Documents, document templating and reusable HTML components. Directly manipulating the DOM in your code can lead to tightly coupling the logic and view. Binding data using custom elements and data attributes leads to highly readable, maintainable view files that are loosely coupled to the application logic. @@ -22,79 +22,51 @@ Directly manipulating the DOM in your code can lead to tightly coupling the logi PHP.G/DomTemplate documentation -## Example usage: Bind dynamic data to a template element +## Example usage: Hello, you! -Consider a page with an unordered list (`