/** * Compiles AngularJS ng-repeat attribute. * Each element's copy is treated and rendered as separate template with it's * own Scope data. Those elements are later appended to element's parent node. * * @todo Think of refactoring methods. * @todo Implement expression cache for better performance. * * @param \DOMElement $domElement DOM element to compile. * @param Scope $scope Scope object. * @return void */ public function compile(\DOMElement $domElement, Scope $scope) { $parsedArray = $this->parseRepeat($domElement); $repeatArray = $scope->getData($parsedArray['array']); /** * Reset interrupting to default value. */ $this->setInterrupt(false); /** * Let's check if variable we're trying to enumerate is array. */ if (is_array($repeatArray) === true) { /** * Helper variables for ng-repeat special scope variables e.g. $index. */ $repeatCount = count($repeatArray); $repeatIndex = 0; foreach ($repeatArray as $repeatKey => $repeatValue) { $subScope = new Scope($scope->getData()); $this->setScopeData($subScope, $parsedArray, $repeatKey, $repeatValue); $this->setScopeSpecial($subScope, $repeatCount, $repeatIndex); /** * Append subcompiled DOM element. */ Utils::appendHTML($domElement->parentNode, $this->subcompile($domElement->cloneNode(true), $subScope)); $repeatIndex++; } /** * We stop further compiling of source DOM element, we want it to * be intact and hidden so we can replace it back on the client side. */ $this->setInterrupt(true); Utils::addClass($domElement, 'ng-hide'); } }
/** * Compiles AngularJS ng-bind-template attributes by evaluating expression inside it * and setting inner HTML. * * @param \DOMElement $domElement DOM element to compile. * @param Scope $scope Scope object containing data for expression. * @return \DOMElement Compiled DOM element. */ public function compile(\DOMElement $domElement, Scope $scope) { $attrValue = $domElement->getAttribute('ng-bind-template'); $foundExpressions = array(); $expression = new Expression($this->phCompile); /** * Find all {{}} expressions. */ preg_match_all('/{{([^}]+)}}/', $attrValue, $foundExpressions); foreach ($foundExpressions[1] as $foundExpression) { /** * Render and cover with span for easy client-site reverting. */ $renderedExpression = $expression->compile($foundExpression, $scope); /** * Replace {{}} expression with rendered value. */ $attrValue = str_replace('{{' . $foundExpression . '}}', $renderedExpression, $attrValue); } if (empty($attrValue) === false) { Utils::appendHTML($domElement, $attrValue); } return $domElement; }
/** * @covers PhCompile\DOM\Utils::appendHTML * @dataProvider appendHtmlProvider */ public function testAppendHTML($html, $appendHtml, $expectedHtml) { $document = Utils::loadHTML($html); $element = $document->getElementsByTagName('span')->item(0); Utils::appendHTML($element, $appendHtml); $renderedHtml = Utils::saveHTML($document); $this->assertSame($expectedHtml, $renderedHtml); }