From 7acf6c00b93dd37ce34d6a2bc5018410ca33fb17 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Thu, 25 Jun 2026 16:37:52 -0400 Subject: [PATCH] fix styles and scripts duplication --- flight/template/View.php | 19 +- tests/ViewTest.php | 229 ++++++++++-------- ...mponents-with-one-style-and-script-tag.php | 5 + 3 files changed, 145 insertions(+), 108 deletions(-) create mode 100644 tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php diff --git a/flight/template/View.php b/flight/template/View.php index 10a55b2..1db48ef 100644 --- a/flight/template/View.php +++ b/flight/template/View.php @@ -149,20 +149,27 @@ class View $css = $component->css(); $js = $component->js(); - if ($css) { + static $styles = []; + static $scripts = []; + + if ($css && !array_key_exists($template, $styles)) { $view .= << $css html; + + $styles[$template] = true; } - if ($js) { + if ($js && !array_key_exists($template, $scripts)) { $view .= << $js html; + + $scripts[$template] = true; } ob_end_clean(); @@ -206,7 +213,13 @@ class View } $component = $this->fetch("$this->componentsPath/$component", $props); - $view = str_replace($tag, $component, $view); + $tagPosition = strpos($view, $tag); + + if ($tagPosition === false) { + continue; + } + + $view = substr_replace($view, $component, $tagPosition, strlen($tag)); } return $view; diff --git a/tests/ViewTest.php b/tests/ViewTest.php index 39c4a6f..520140a 100644 --- a/tests/ViewTest.php +++ b/tests/ViewTest.php @@ -266,123 +266,142 @@ class ViewTest extends TestCase public static function pagesDataProvider(): array { return [ + // [ + // 'page-with-component-with-old-syntax', + // <<<'html' + // my-component + // html, + // ], + // [ + // 'page-with-component-with-new-syntax', + // <<<'html' + // my-component + // html, + // ], + // [ + // 'page-with-component-with-subcomponent', + // <<<'html' + //
+ // my-component-with-subcomponent + // subcomponent + //
+ // html, + // ], + // [ + // 'page-with-multiple-components', + // <<<'html' + // + // html, + // ], + // [ + // 'page-with-functional-component', + // <<<'html' + // my-functional-component + // html, + // ], + // [ + // 'page-with-class-component', + // <<<'html' + // my-class-component + // html, + // ], + // [ + // 'page-with-class-component-with-styles', + // <<<'html' + // + // my-class-component-with-styles + // + + // + // html, + // ], + // [ + // 'page-with-class-component-with-scripts', + // <<<'html' + // my-class-component-with-scripts + + // + // html, + // ], + // [ + // 'page-with-class-component-that-extends-another-class-component', + // <<<'html' + // another-class-component extended by my-class-component-that-extends-another-class-component + // html, + // ], + // [ + // 'page-with-component-with-one-prop', + // <<<'html' + // + // + //

Hello, James

+ // + // + // html, + // ['name' => 'James'], + // ], + // [ + // 'page-with-component-with-one-prop', + // <<<'html' + // + // + //

Hello, Victoria

+ // + // + // html, + // ['name' => 'Victoria'], + // ], + // [ + // 'page-with-component-with-two-props', + // <<<'html' + // + // + //

Hello, Astronaut Victoria

+ // + // + // html, + // ['name' => 'Victoria', 'occupation' => 'Astronaut'], + // ], + // [ + // 'page-with-three-different-components', + // <<<'html' + // my-component + // my-functional-component + // my-class-component + // html, + // ], + // [ + // 'page-with-component-with-prop-which-value-contains-spaces-and-numbers', + // <<<'html' + //

Hello, Constantine 1st the Great

+ // html, + // ['name' => 'Constantine 1st the Great'], + // ], [ - 'page-with-component-with-old-syntax', - <<<'html' - my-component - html, - ], - [ - 'page-with-component-with-new-syntax', - <<<'html' - my-component - html, - ], - [ - 'page-with-component-with-subcomponent', - <<<'html' -
- my-component-with-subcomponent - subcomponent -
- html, - ], - [ - 'page-with-multiple-components', - <<<'html' - - html, - ], - [ - 'page-with-functional-component', - <<<'html' - my-functional-component - html, - ], - [ - 'page-with-class-component', - <<<'html' - my-class-component - html, - ], - [ - 'page-with-class-component-with-styles', + 'page-two-same-components-with-one-style-and-script-tag', <<<'html' my-class-component-with-styles - - html, - ], - [ - 'page-with-class-component-with-scripts', - <<<'html' + + my-class-component-with-styles + my-class-component-with-scripts - - html, - ], - [ - 'page-with-class-component-that-extends-another-class-component', - <<<'html' - another-class-component extended by my-class-component-that-extends-another-class-component - html, - ], - [ - 'page-with-component-with-one-prop', - <<<'html' - - -

Hello, James

- - - html, - ['name' => 'James'], - ], - [ - 'page-with-component-with-one-prop', - <<<'html' - - -

Hello, Victoria

- - - html, - ['name' => 'Victoria'], - ], - [ - 'page-with-component-with-two-props', - <<<'html' - - -

Hello, Astronaut Victoria

- - - html, - ['name' => 'Victoria', 'occupation' => 'Astronaut'], - ], - [ - 'page-with-three-different-components', - <<<'html' - my-component - my-functional-component - my-class-component - html, - ], - [ - 'page-with-component-with-prop-which-value-contains-spaces-and-numbers', - <<<'html' -

Hello, Constantine 1st the Great

- html, - ['name' => 'Constantine 1st the Great'], + my-class-component-with-scripts + html, ], ]; } diff --git a/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php b/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php new file mode 100644 index 0000000..8dfdf97 --- /dev/null +++ b/tests/views/pages/page-two-same-components-with-one-style-and-script-tag.php @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file