Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
jreviews committed Apr 16, 2024
2 parents d04eb38 + e39ee96 commit 31542b7
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 38 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# Changelog

## [Unreleased](https://github.com/clickfwd/yoyo/compare/0.9.0...develop)
## [Unreleased](https://github.com/clickfwd/yoyo/compare/0.9.1...develop)

## [0.9.1 (2024-04-16)](https://github.com/clickfwd/yoyo/compare/0.9.0...0.9.1)

- Fix Safari/iOS errors due to evt.target and evt.srcElement now being null.
- Add support for port in UrlStateManagerService.php
- PHP 8.2/8.3 compat
- Fix ResponseHeaders::refresh error due to missing parameter.
- Fix headers already sent error when setting status code in response
- Ensure components are compiled only once.
- Bump htmx to v1.9.4 and include new config options.
- New Request::set, Request::triggerName and Request::header methods.
- New Response::reselect method for the HX-Reselect header.
- New New Yoyo::actionArgs method.

## [0.9.0 (2023-04-02)](https://github.com/clickfwd/yoyo/compare/0.8.1...0.9.0)

Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"framework",
"yoyo"
],
"version": "0.9.0",
"version": "0.9.1",
"license": "MIT",
"homepage": "https://github.com/Clickfwd/yoyo",
"support": {
Expand All @@ -20,8 +20,8 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": "^7.3|^8.0|^8.1",
"illuminate/container": "^8.0||^9.0"
"php": "^7.3|^8.0|^8.1|^8.2|^8.3",
"illuminate/container": "^8.0||^9.0||^10.0"
},
"require-dev": {
"phpunit/phpunit": "^9.3",
Expand Down
20 changes: 10 additions & 10 deletions src/assets/js/yoyo.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@
},
afterProcessNode(evt) {
// Create non-existent target
if (evt.srcElement) {
if (evt.detail.elt) {
this.createNonExistentIdTarget(
evt.srcElement.getAttribute('hx-target')
evt.detail.elt.getAttribute('hx-target')
)
}

// Initialize spinners
let component

if (!evt.srcElement || !isComponent(evt.srcElement)) {
if (!evt.detail.elt || !isComponent(evt.detail.elt)) {
// For innerHTML swap find the component root node
component = YoyoEngine.closest(
evt.detail.elt,
'[hx-swap~=innerHTML]'
)
} else {
component = getComponent(evt.srcElement)
component = getComponent(evt.detail.elt)
}

if (!component) {
Expand All @@ -69,7 +69,7 @@
initializeComponentSpinners(component)
},
bootstrapRequest(evt) {
const elt = evt.target
const elt = evt.detail.elt
let component = getComponent(elt)
const componentName = getComponentName(component)

Expand Down Expand Up @@ -133,13 +133,13 @@
let component = getComponentById(evt.detail.target.id)

if (!component) {
if (!evt.target) {
if (!evt.detail.elt) {
return
}
// Needed when using yoyo:select to replace a specific part of the response
// so stop spinning callbacks are run to remove animations in the parts of the component
// that were not replaced
component = getComponent(evt.target)
component = getComponent(evt.detail.elt)
if (component) {
spinningStop(component)
}
Expand Down Expand Up @@ -713,7 +713,7 @@ YoyoEngine.defineExtension('yoyo', {
}

if (name === 'htmx:configRequest') {
if (!evt.target) return
if (!evt.detail.elt) return

Yoyo.bootstrapRequest(evt)
}
Expand Down Expand Up @@ -761,7 +761,7 @@ YoyoEngine.defineExtension('yoyo', {
}

if (name === 'htmx:beforeSwap') {
if (!evt.target) return
if (!evt.detail.elt) return

// Add triggering element info to event detail so it can be read in after swap events
// For example to push the href url to browser history using the href from the element that's no longer present on the page
Expand Down Expand Up @@ -794,7 +794,7 @@ YoyoEngine.defineExtension('yoyo', {
// Push component response to history cache
// Make sure we trigger once for the new element - this was failing in Safari mobile
// Causing a duplicate snapshot
if (!evt.target || !evt.target.isConnected) return
if (!evt.detail.elt || !evt.detail.elt.isConnected) return

Yoyo.afterSettleActions(evt)
}
Expand Down
11 changes: 9 additions & 2 deletions src/yoyo/Concerns/ResponseHeaders.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ public function redirect($url)

public function refresh()
{
$this->header('HX-Refresh');
$this->header('HX-Refresh', 'true');

return $this;
}

public function replace($url)
public function replaceUrl($url)
{
$this->header('HX-Replace-Url', $url);

Expand All @@ -46,6 +46,13 @@ public function reswap($swap)
return $this;
}

public function reselect($selector)
{
$this->header('HX-Reselect', $selector);

return $this;
}

public function retarget($selector)
{
$this->header('HX-Retarget', $selector);
Expand Down
4 changes: 4 additions & 0 deletions src/yoyo/QueryString.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public function getPageQueryParams()
// If a query string value matches the default value, remove it from the URL

foreach ($queryParams as $key => $val) {
if (is_object($val) && method_exists($val, 'toArray')) {
$queryParams[$key] = $val->toArray();
}

if (isset($this->defaults[$key]) && $val === $this->defaults[$key] || $val === '') {
unset($queryParams[$key]);
}
Expand Down
24 changes: 24 additions & 0 deletions src/yoyo/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ public function startsWith($prefix)
return $vars;
}

public function set($key, $value)
{
$this->request[$key] = $value;

return $this;
}

public function merge($data)
{
$this->request = array_merge($this->request, $data);

return $this;
}

public function drop($key)
{
$this->dropped[] = $key;
Expand Down Expand Up @@ -145,4 +159,14 @@ public function triggerId()
{
return $this->server['HTTP_HX_TRIGGER'];
}

public function triggerName()
{
return $this->server['HTTP_HX_TRIGGER_NAME'] ?? null;
}

public function header($name)
{
return $this->server['HTTP_'.strtoupper($name)] ?? null;
}
}
34 changes: 19 additions & 15 deletions src/yoyo/Services/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,35 @@ class Configuration

private static $options;

public static $htmx = '1.8.4';
public static $htmx = '1.9.4';

protected static $allowedConfigOptions = [
'addedClass',
'allowEval',
'attributesToSettle',
'defaultFocusScroll',
'defaultSettleDelay',
'defaultSwapDelay',
'defaultSwapStyle',
'disableSelector',
'historyCacheSize',
'historyEnabled',
'historyCacheSize',
'refreshOnHistoryMiss',
'defaultSwapStyle',
'defaultSwapDelay',
'defaultSettleDelay',
'includeIndicatorStyles',
'indicatorClass',
'inlineScriptNonce',
'refreshOnHistoryMiss',
'requestClass',
'scrollBehavior',
'addedClass',
'settlingClass',
'swappingClass',
'timeout',
'useTemplateFragments',
'allowEval',
'inlineScriptNonce',
'attributesToSettle',
'withCredentials',
'timeout',
'wsReconnectDelay',
'wsBinaryType',
'disableSelector',
'useTemplateFragments',
'scrollBehavior',
'defaultFocusScroll',
'getCacheBusterParam',
'globalViewTransitions',
'methodsThatUseUrlParams',
];

public function __construct($options)
Expand Down
7 changes: 3 additions & 4 deletions src/yoyo/Services/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ public function send(string $content = ''): string
header("$key: $value");
}

if ($this->statusCode == 204) {
http_response_code(204);
// Prevent headers already sent error
if (! headers_sent()) {
http_response_code($this->statusCode ?? 200);
}

http_response_code($this->statusCode ?? 200);

return $content ?: '';
}

Expand Down
3 changes: 2 additions & 1 deletion src/yoyo/Services/UrlStateManagerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public function pushState($queryParams)

$parsedUrl = parse_url($this->currentUrl);

$url = $parsedUrl['scheme'].'://'.$parsedUrl['host'].$parsedUrl['path'].($queryParams ? '?'.http_build_query($queryParams) : '');
$port = isset($parsedUrl['port']) ? (':'.$parsedUrl['port']) : '';
$url = $parsedUrl['scheme'].'://'.$parsedUrl['host'].$port.$parsedUrl['path'].($queryParams ? '?'.http_build_query($queryParams) : '');

if ($url !== $this->currentUrl) {
$response->header('Yoyo-Push', $url);
Expand Down
7 changes: 7 additions & 0 deletions src/yoyo/Yoyo.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ public function action($action): self
return $this;
}

public function actionArgs(...$args)
{
$this->request()->merge(['actionArgs' => $args]);

return $this;
}

/**
* Renders the component on initial page load.
*/
Expand Down
9 changes: 7 additions & 2 deletions src/yoyo/YoyoCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ public function compile($html): string
$prefix_finder = self::YOYO_PREFIX_FINDER;

// U modifier needed to match children tags when there are no line breaks in the HTML code

$html = preg_replace('/ '.$prefix.':(.*)="(.*)"/U', " $prefix_finder $prefix:\$1=\"\$2\"", $html);
$html = preg_replace('/ ' . $prefix . ':(.*)=\'(.*)\'/U', " {$prefix_finder} {$prefix}:\$1='\$2'", $html);

$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
// Converts non-ascii characters to numeric html entities
$html = mb_encode_numericentity($html, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');

$dom = new DOMDocument();

Expand Down Expand Up @@ -193,6 +193,11 @@ protected function addComponentRootAttributes($element)
return;
}

// Skip when component already compiled
if ($element->hasAttribute(self::yoprefix('name')) && $element->hasAttribute(self::hxprefix('vals'))) {
return;
}

$element->setAttribute(self::YOYO_PREFIX, '');

$element->setAttribute(self::YOYO_PREFIX_FINDER, '');
Expand Down
10 changes: 10 additions & 0 deletions tests/Unit/YoyoCompileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,13 @@
expect(compile_html_with_vars('foo', '<div id="foo" yoyo:props="foo"></div>', ['foo' => 'bar']))
->toContain(hxattr('vals', encode_vals([yoprefix_value('id') => 'foo', 'foo' => 'bar'])));
});

it('correctly compiles component with non-ascii characters', function () {
expect(compile_html('foo', '<div><p>áéíóü</p></div>'))
->toContain('áéíóü');
});

it('correctly compiles component with Chinese characters', function () {
expect(compile_html('foo', '<div><p>极简、极速、极致、 海豚PHP、PHP开发框架、后台框架</p></div>'))
->toContain('极简、极速、极致、 海豚PHP、PHP开发框架、后台框架');
});
4 changes: 4 additions & 0 deletions tests/app/Yoyo/ActionArguments.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

class ActionArguments extends Component
{
protected $a;

protected $b;

public function someAction($a, $b)
{
$this->a = $a;
Expand Down
6 changes: 6 additions & 0 deletions tests/app/Yoyo/CounterDynamicProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@

use Clickfwd\Yoyo\Component;

#[\AllowDynamicProperties]
class CounterDynamicProperties extends Component
{
public function getQueryString()
{
return $this->getDynamicProperties();
}

/**
* The 'count' property value is not known ahead of time and can be set programatically;
*
* @return void
*/
public function getDynamicProperties()
{
return ['count'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

class DependencyInjectionClassWithNamedArgumentMapping extends Component
{
protected $id;

protected $post;

// $foo variable passed to component is automaticaly injected in Post::__constructor
Expand Down

0 comments on commit 31542b7

Please sign in to comment.