From 4983bf67785cf569ab29e0dc39d7125b6cac3177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 17 Feb 2023 01:05:40 +0100 Subject: [PATCH 1/6] rename fxArgs/fxStatements props --- src/Js/JsFunction.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Js/JsFunction.php b/src/Js/JsFunction.php index ce4c1aedf5..6c2d1325f7 100644 --- a/src/Js/JsFunction.php +++ b/src/Js/JsFunction.php @@ -14,10 +14,10 @@ class JsFunction implements JsExpressionable use WarnDynamicPropertyTrait; /** @var array */ - public $fxArgs; + public $args; /** @var array */ - public $fxStatements = []; + public $statements = []; /** @var bool add preventDefault(event) to generated method */ public $preventDefault = false; @@ -33,7 +33,7 @@ class JsFunction implements JsExpressionable */ public function __construct(array $args, array $statements) { - $this->fxArgs = $args; + $this->args = $args; foreach ($statements as $key => $value) { if (is_int($key)) { @@ -41,7 +41,7 @@ public function __construct(array $args, array $statements) continue; } - $this->fxStatements[] = $value; + $this->statements[] = $value; } else { $this->{$key} = $value; } @@ -52,17 +52,17 @@ public function jsRender(): string { $pre = ''; if ($this->preventDefault) { - $this->fxArgs = ['event']; + $this->args = ['event']; $pre .= "\n" . $this->indent . ' event.preventDefault();'; } if ($this->stopPropagation) { - $this->fxArgs = ['event']; + $this->args = ['event']; $pre .= "\n" . $this->indent . ' event.stopPropagation();'; } - $output = 'function (' . implode(', ', $this->fxArgs) . ') {' + $output = 'function (' . implode(', ', $this->args) . ') {' . $pre; - foreach ($this->fxStatements as $statement) { + foreach ($this->statements as $statement) { $js = $statement->jsRender(); $output .= "\n" . $this->indent . ' ' . $js . (!preg_match('~[;}]\s*$~', $js) ? ';' : ''); From df9ba696dc61d95d2568b71370d7b6d8daa1a6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 17 Feb 2023 19:36:47 +0100 Subject: [PATCH 2/6] improve phpdoc --- src/Form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form.php b/src/Form.php index 1982a2b1d8..3786ca8f01 100644 --- a/src/Form.php +++ b/src/Form.php @@ -32,7 +32,7 @@ class Form extends View public $ui = 'form'; public $defaultTemplate = 'form.html'; - /** @var Callback Callback handling form submission. */ + /** @var JsCallback Callback handling form submission. */ public $cb; /** From b07e43caba6bb907fc6ded9661601e52e5e67ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 17 Feb 2023 21:50:21 +0100 Subject: [PATCH 3/6] strong type JsSse::send() --- src/Console.php | 18 +++++++++++------- src/JsSse.php | 4 +--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Console.php b/src/Console.php index 33110fce82..286c44d0c8 100644 --- a/src/Console.php +++ b/src/Console.php @@ -209,8 +209,11 @@ protected function outputHtmlWithoutPre(string $messageHtml, array $context = [] }, $messageHtml); $this->_outputBypass = true; - $this->sse->send($this->js()->append($messageHtml)); - $this->_outputBypass = false; + try { + $this->sse->send($this->js()->append($messageHtml)); + } finally { + $this->_outputBypass = false; + } return $this; } @@ -225,15 +228,16 @@ protected function renderView(): void /** * Executes a JavaScript action. * - * @param JsExpressionable $js - * * @return $this */ - public function send($js) + public function send(JsExpressionable $js) { $this->_outputBypass = true; - $this->sse->send($js); - $this->_outputBypass = false; + try { + $this->sse->send($js); + } finally { + $this->_outputBypass = false; + } return $this; } diff --git a/src/JsSse.php b/src/JsSse.php index 55f0937864..cfadce6e2c 100644 --- a/src/JsSse.php +++ b/src/JsSse.php @@ -58,10 +58,8 @@ public function jsExecute(): JsExpression /** * Sending an SSE action. - * - * @param JsExpressionable $action */ - public function send($action, bool $success = true): void + public function send(JsExpressionable $action, bool $success = true): void { if ($this->browserSupport) { $ajaxec = $this->getAjaxec($action); From 961b7c6fc488a956bf18aafa2468ce480f10e65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 17 Feb 2023 22:55:44 +0100 Subject: [PATCH 4/6] use single quotes --- src/Dropdown.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dropdown.php b/src/Dropdown.php index c13e479f7f..5ce1911552 100644 --- a/src/Dropdown.php +++ b/src/Dropdown.php @@ -46,7 +46,7 @@ public function onChange(\Closure $fx): void // setting dropdown option for using callback url. $this->dropdownOptions['onChange'] = new JsFunction(['value', 'name', 't'], [ new JsExpression( - "if ($(this).data('currentValue') != value) { $(this).atkAjaxec({ url: [url], urlOptions: { item: value } }); $(this).data('currentValue', value); }", + 'if ($(this).data(\'currentValue\') != value) { $(this).atkAjaxec({ url: [url], urlOptions: { item: value } }); $(this).data(\'currentValue\', value); }', ['url' => $this->cb->getJsUrl()] ), ]); From 1de74a7e8ccde4d1f4361025a5979fb6eb91c27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 17 Feb 2023 16:44:20 +0100 Subject: [PATCH 5/6] Form\Control::onChange() should not accept JS as string --- demos/form-control/input2.php | 30 +++++++++++++----------------- docs/form-control.rst | 2 +- src/Form.php | 2 +- src/Form/Control.php | 13 ++++--------- src/Form/Control/Calendar.php | 3 --- src/Form/Control/Radio.php | 5 ----- src/ItemsPerPageSelector.php | 21 +++++++++++---------- src/Js/JsReload.php | 5 +---- src/JsCallback.php | 2 +- src/Table/Column.php | 6 +++--- 10 files changed, 35 insertions(+), 54 deletions(-) diff --git a/demos/form-control/input2.php b/demos/form-control/input2.php index 66c80bf9c7..a334ee35f6 100644 --- a/demos/form-control/input2.php +++ b/demos/form-control/input2.php @@ -153,34 +153,30 @@ $group = $form->addGroup('Calendar'); $c1 = $group->addControl('c1', new Form\Control\Calendar(['type' => 'date'])); $c2 = $group->addControl('c2', new Form\Control\Calendar(['type' => 'date'])); -$c3 = $group->addControl('c3', new Form\Control\Calendar(['type' => 'date'])); -$c1->onChange('console.log(\'c1 changed: \' + date + \', \' + text + \', \' + mode)'); -$c2->onChange(new JsExpression('console.log(\'c2 changed: \' + date + \', \' + text + \', \' + mode)')); -$c3->onChange([ - new JsExpression('console.log(\'c3 changed: \' + date + \', \' + text + \', \' + mode)'), - new JsExpression('console.log(\'c3 really changed: \' + date + \', \' + text + \', \' + mode)'), +$c1->onChange(new JsExpression('console.log(\'c1 changed: \' + date + \', \' + text + \', \' + mode)')); +$c2->onChange([ + new JsExpression('console.log(\'c2 changed: \' + date + \', \' + text + \', \' + mode)'), + new JsExpression('console.log(\'c2 really changed: \' + date + \', \' + text + \', \' + mode)'), ]); $group = $form->addGroup('Line'); $f1 = $group->addControl('f1'); $f2 = $group->addControl('f2'); $f3 = $group->addControl('f3'); -$f4 = $group->addControl('f4'); -$f1->onChange('console.log(\'f1 changed\')'); -$f2->onChange(new JsExpression('console.log(\'f2 changed\')')); -$f3->onChange([ - new JsExpression('console.log(\'f3 changed\')'), - new JsExpression('console.log(\'f3 really changed\')'), +$f1->onChange(new JsExpression('console.log(\'f1 changed\')')); +$f2->onChange([ + new JsExpression('console.log(\'f2 changed\')'), + new JsExpression('console.log(\'f2 really changed\')'), ]); -$f4->onChange(function () { - return new JsExpression('console.log(\'f4 changed\')'); +$f3->onChange(function () { + return new JsExpression('console.log(\'f3 changed\')'); }); $group = $form->addGroup('CheckBox'); $b1 = $group->addControl('b1', new Form\Control\Checkbox()); -$b1->onChange('console.log(\'b1 changed\')'); +$b1->onChange(new JsExpression('console.log(\'b1 changed\')')); $group = $form->addGroup(['Dropdown', 'width' => 'three']); $d1 = $group->addControl('d1', new Form\Control\Dropdown([ @@ -191,7 +187,7 @@ 'file' => ['File', 'icon' => 'file'], ], ])); -$d1->onChange('console.log(\'Dropdown changed\')'); +$d1->onChange(new JsExpression('console.log(\'Dropdown changed\')')); $group = $form->addGroup('Radio'); $r1 = $group->addControl('r1', new Form\Control\Radio([ @@ -202,7 +198,7 @@ 'File', ], ])); -$r1->onChange('console.log(\'radio changed\')'); +$r1->onChange(new JsExpression('console.log(\'radio changed\')')); Header::addTo($app, ['Line ends of Textarea']); diff --git a/docs/form-control.rst b/docs/form-control.rst index e657177027..7612e7aa32 100644 --- a/docs/form-control.rst +++ b/docs/form-control.rst @@ -296,7 +296,7 @@ onChange event .. php:method:: onChange($expression) It's prefferable to use this short-hand version of on('change', 'input', $expression) method. -$expression argument can be string, JsExpression, array of JsExpressions or even PHP callback function. +$expression argument can be JsExpression, array of JsExpressions or even PHP callback function. // simple string $f1 = $form->addControl('f1'); diff --git a/src/Form.php b/src/Form.php index 3786ca8f01..264ea5b8f0 100644 --- a/src/Form.php +++ b/src/Form.php @@ -43,7 +43,7 @@ class Form extends View * Note: * When using your own change handler * on an input field, set useDefault parameter to false. - * ex: $input->onChange('console.log(), false) + * ex: $input->onChange(new JsExpression('console.log()), false) * Otherwise, change event is not propagate to all event handler * and leaving page might not be prevent. * diff --git a/src/Form/Control.php b/src/Form/Control.php index 56bee239ec..0cda391390 100644 --- a/src/Form/Control.php +++ b/src/Form/Control.php @@ -132,7 +132,7 @@ protected function renderTemplateToHtml(): string * Shorthand method for on('change') event. * Some input fields, like Calendar, could call this differently. * - * If $expr is string or JsExpression, then it will execute it instantly. + * If $expr is JsExpressionable, then it will execute it instantly. * If $expr is callback method, then it'll make additional request to webserver. * * Could be preferable to set useDefault to false. For example when @@ -140,19 +140,14 @@ protected function renderTemplateToHtml(): string * Otherwise, change handler will not be propagate to all handlers. * * Examples: - * $control->onChange('console.log(\'changed\')'); * $control->onChange(new JsExpression('console.log(\'changed\')')); - * $control->onChange('$(this).parents(\'.form\').form(\'submit\')'); + * $control->onChange(new JsExpression('$(this).parents(\'.form\').form(\'submit\')')); * - * @param string|JsExpression|array|\Closure $expr - * @param array|bool $defaults + * @param JsExpressionable|array|\Closure $expr + * @param array|bool $defaults */ public function onChange($expr, $defaults = []): void { - if (is_string($expr)) { - $expr = new JsExpression($expr); - } - if (is_bool($defaults)) { $defaults = $defaults ? [] : ['preventDefault' => false, 'stopPropagation' => false]; } diff --git a/src/Form/Control/Calendar.php b/src/Form/Control/Calendar.php index 68f7a6cebb..8b40bec20a 100644 --- a/src/Form/Control/Calendar.php +++ b/src/Form/Control/Calendar.php @@ -70,9 +70,6 @@ protected function renderView(): void public function onChange($expr, $default = []): void { - if (is_string($expr)) { - $expr = new JsExpression($expr); - } if (!is_array($expr)) { $expr = [$expr]; } diff --git a/src/Form/Control/Radio.php b/src/Form/Control/Radio.php index 4e5cc5e178..09b7290333 100644 --- a/src/Form/Control/Radio.php +++ b/src/Form/Control/Radio.php @@ -5,7 +5,6 @@ namespace Atk4\Ui\Form\Control; use Atk4\Ui\Form; -use Atk4\Ui\Js\JsExpression; use Atk4\Ui\Lister; class Radio extends Form\Control @@ -58,10 +57,6 @@ protected function renderView(): void public function onChange($expr, $defaults = []): void { - if (is_string($expr)) { - $expr = new JsExpression($expr); - } - if (is_bool($defaults)) { $defaults = $defaults ? [] : ['preventDefault' => false, 'stopPropagation' => false]; } diff --git a/src/ItemsPerPageSelector.php b/src/ItemsPerPageSelector.php index 5fe4c35679..9d5af1b649 100644 --- a/src/ItemsPerPageSelector.php +++ b/src/ItemsPerPageSelector.php @@ -72,20 +72,21 @@ protected function renderView(): void foreach ($this->pageLengthItems as $key => $item) { $menuItems[] = ['name' => $item, 'value' => $item]; } - // set Fomantic-UI dropdown onChange function. - $function = 'function (value, text, item) { - if (value === undefined || value === \'\' || value === null) return; - $(this) - .api({ - on:\'now\', - url:\'' . $this->cb->getUrl() . '\', - data:{ipp:value} + + $function = new JsExpression('function (value, text, item) { + if (value === undefined || value === \'\' || value === null) { + return; + } + $(this).api({ + on: \'now\', + url: \'' . $this->cb->getUrl() . '\', + data: {ipp:value} }); - }'; + }'); $this->js(true)->dropdown([ 'values' => $menuItems, - 'onChange' => new JsExpression($function), + 'onChange' => $function, ]); parent::renderView(); diff --git a/src/Js/JsReload.php b/src/Js/JsReload.php index fb8ec070f3..b6f9cde8f0 100644 --- a/src/Js/JsReload.php +++ b/src/Js/JsReload.php @@ -20,10 +20,7 @@ class JsReload implements JsExpressionable /** @var JsExpression|null A Js function to execute after reload is complete and onSuccess is execute. */ public $afterSuccess; - /** - * If defined, they will be added at the end of your URL. - * Value in ARG can be either string or JsExpressionable. - */ + /** @var array Added at the end of your URL. */ public array $args = []; /** diff --git a/src/JsCallback.php b/src/JsCallback.php index 107fee5beb..0caf27a8c9 100644 --- a/src/JsCallback.php +++ b/src/JsCallback.php @@ -181,7 +181,7 @@ private function _getProperAction($response): JsExpressionable { if ($response instanceof View) { $response = $this->_jsRenderIntoModal($response); - } elseif (is_string($response)) { + } elseif (is_string($response)) { // TODO alert() should be removed $response = new JsExpression('alert([])', [$response]); } diff --git a/src/Table/Column.php b/src/Table/Column.php index bc20e47588..dc47b7c693 100644 --- a/src/Table/Column.php +++ b/src/Table/Column.php @@ -164,7 +164,7 @@ public function setHeaderDropdown($items, string $icon = 'caret square down', st $cb = Column\JsHeader::addTo($this->table); - $function = 'function (value, text, item) { + $function = new JsExpression('function (value, text, item) { if (value === undefined || value === \'\' || value === null) { return; } @@ -173,13 +173,13 @@ public function setHeaderDropdown($items, string $icon = 'caret square down', st url: \'' . $cb->getJsUrl() . '\', data: { item: value, id: $(this).data(\'menu-id\') } }); - }'; + }'); $chain = new Jquery('#' . $id); $chain->dropdown([ 'action' => 'hide', 'values' => $items, - 'onChange' => new JsExpression($function), + 'onChange' => $function, ]); // will stop grid column from being sorted. From 5aae0293b7b16e71870353290d49d50fd8acd58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sat, 18 Feb 2023 13:55:26 +0100 Subject: [PATCH 6/6] land some safe changes from 1997 PR --- demos/interactive/popup.php | 2 -- docs/callbacks.rst | 6 +++--- docs/rightpanel.rst | 2 +- phpstan.neon.dist | 3 --- src/Accordion.php | 11 ++++++----- src/App.php | 3 ++- src/CardDeck.php | 8 ++++---- src/Crud.php | 15 +++++---------- src/Form.php | 14 +++++++------- src/Form/Control.php | 2 +- src/Form/Control/Checkbox.php | 2 +- src/Grid.php | 14 ++------------ src/HtmlTemplate.php | 2 +- src/Js/JsExpression.php | 2 +- src/Js/JsFunction.php | 19 ++++++++++--------- src/Js/JsReload.php | 4 ++-- src/JsCallback.php | 5 +++-- src/JsPaginator.php | 5 +++-- src/JsSortable.php | 3 ++- src/Loader.php | 3 ++- src/Modal.php | 12 ++++++------ src/Panel/Right.php | 20 ++++++++++---------- src/Popup.php | 3 ++- src/ProgressBar.php | 8 ++------ src/Table.php | 4 ++-- src/Table/Column.php | 6 +++--- src/Table/Column/ActionButtons.php | 2 -- src/Table/Column/Checkbox.php | 5 ++--- src/UserAction/BasicExecutor.php | 2 +- src/UserAction/ConfirmationExecutor.php | 2 +- src/UserAction/JsCallbackExecutor.php | 2 +- src/UserAction/StepExecutorTrait.php | 2 +- src/View.php | 20 +++++++------------- src/VueComponent/InlineEdit.php | 5 +++-- src/Wizard.php | 9 ++++----- 35 files changed, 101 insertions(+), 126 deletions(-) diff --git a/demos/interactive/popup.php b/demos/interactive/popup.php index 9723ed4df9..2291620c94 100644 --- a/demos/interactive/popup.php +++ b/demos/interactive/popup.php @@ -142,8 +142,6 @@ protected function init(): void * Associate your shelf with cart, so that when item is clicked, the content of a * cart is updated. * - * Also - you can supply jsAction to execute when this happens. - * * @param JsExpressionable|array $jsAction */ public function linkCart(View $cart, $jsAction = null): void diff --git a/docs/callbacks.rst b/docs/callbacks.rst index a6dd8cb835..77ec61de20 100644 --- a/docs/callbacks.rst +++ b/docs/callbacks.rst @@ -279,7 +279,7 @@ will send browser screen width back to the callback:: $cb->set(function (\Atk4\Ui\Js\Jquery $j, $arg1) { return 'width is ' . $arg1; - }, [new \Atk4\Ui\Js\JsExpression( '$(window).width()' )]); + }, [new \Atk4\Ui\Js\JsExpression('$(window).width()')]); $label->detail = $cb->getUrl(); $label->on('click', $cb); @@ -292,7 +292,7 @@ also supports argument passing:: $label->on('click', function (Jquery $j, $arg1) { return 'width is ' . $arg1; - }, ['confirm' => 'sure?', 'args' => [new \Atk4\Ui\Js\JsExpression( '$(window).width()' )]]); + }, ['confirm' => 'sure?', 'args' => [new \Atk4\Ui\Js\JsExpression('$(window).width()')]]); If you do not need to specify confirm, you can actually pass arguments in a key-less array too:: @@ -300,7 +300,7 @@ If you do not need to specify confirm, you can actually pass arguments in a key- $label->on('click', function (Jquery $j, $arg1) { return 'width is ' . $arg1; - }, [new \Atk4\Ui\Js\JsExpression( '$(window).width()' )]); + }, [new \Atk4\Ui\Js\JsExpression('$(window).width()')]); Refering to event origin diff --git a/docs/rightpanel.rst b/docs/rightpanel.rst index 115d5ce422..a4e3b38fe1 100644 --- a/docs/rightpanel.rst +++ b/docs/rightpanel.rst @@ -64,4 +64,4 @@ This method may take up to three arguments. to the trigger element as long as the panel remains open. This help visualize, which element has trigger the panel opening. - $jsTrigger: a JsExpression that represent the jQuery object where the data property reside. Default to $(this). + $jsTrigger: JS expression that represent the jQuery object where the data property reside. Default to $(this). diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 59ac458b02..6825543fa5 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -187,9 +187,6 @@ parameters: - path: 'src/Table/Column.php' message: '~^Call to an undefined method Atk4\\Ui\\AbstractView::setHoverable\(\)\.$~' - - - path: 'src/Table/Column.php' - message: '~^Call to an undefined method Atk4\\Ui\\JsCallback::onSelectItem\(\)\.$~' - path: 'src/Table/Column/Checkbox.php' message: '~^Call to an undefined method Atk4\\Ui\\Js\\JsChain::join\(\)\.$~' diff --git a/src/Accordion.php b/src/Accordion.php index b402a282c1..c73872824b 100644 --- a/src/Accordion.php +++ b/src/Accordion.php @@ -5,6 +5,7 @@ namespace Atk4\Ui; use Atk4\Ui\Js\JsChain; +use Atk4\Ui\Js\JsExpressionable; /** * Accordion is a View holding accordion sections. @@ -71,7 +72,7 @@ public function activate($section): void * * @return JsChain */ - public function jsOpen($section, $when = false) + public function jsOpen($section, $when = false): JsExpressionable { return $this->jsBehavior('open', [$this->getSectionIdx($section)], $when); } @@ -81,7 +82,7 @@ public function jsOpen($section, $when = false) * * @return JsChain */ - public function jsCloseOthers($when = false) + public function jsCloseOthers($when = false): JsExpressionable { return $this->jsBehavior('close others', [], $when); } @@ -92,7 +93,7 @@ public function jsCloseOthers($when = false) * * @return JsChain */ - public function jsClose($section, $when = false) + public function jsClose($section, $when = false): JsExpressionable { return $this->jsBehavior('close', [$this->getSectionIdx($section)], $when); } @@ -103,7 +104,7 @@ public function jsClose($section, $when = false) * * @return JsChain */ - public function jsToggle($section, $when = false) + public function jsToggle($section, $when = false): JsExpressionable { return $this->jsBehavior('toggle', [$this->getSectionIdx($section)], $when); } @@ -119,7 +120,7 @@ public function jsToggle($section, $when = false) * * @return JsChain */ - public function jsBehavior($behavior, array $args, $when = false) + public function jsBehavior($behavior, array $args, $when = false): JsExpressionable { return $this->js($when)->accordion($behavior, ...$args); } diff --git a/src/App.php b/src/App.php index e57db83305..604c648100 100644 --- a/src/App.php +++ b/src/App.php @@ -17,6 +17,7 @@ use Atk4\Ui\Exception\LateOutputError; use Atk4\Ui\Exception\UnhandledCallbackExceptionError; use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; use Atk4\Ui\Persistence\Ui as UiPersistence; use Atk4\Ui\UserAction\ExecutorFactory; use Psr\Log\LoggerInterface; @@ -790,7 +791,7 @@ public function redirect($page, bool $permanent = false): void * * @param string|array $page Destination URL or page/arguments */ - public function jsRedirect($page, bool $newWindow = false): JsExpression + public function jsRedirect($page, bool $newWindow = false): JsExpressionable { return new JsExpression('window.open([], [])', [$this->url($page), $newWindow ? '_blank' : '_top']); } diff --git a/src/CardDeck.php b/src/CardDeck.php index e61670e639..0a44cf23b7 100644 --- a/src/CardDeck.php +++ b/src/CardDeck.php @@ -225,7 +225,7 @@ protected function initActionExecutor(Model\UserAction $action): ExecutorInterfa protected function jsExecute($return, Model\UserAction $action) { if (is_string($return)) { - return $this->getNotifier($action, $return); + return $this->jsCreateNotifier($action, $return); } elseif (is_array($return) || $return instanceof JsExpressionable) { return $return; } elseif ($return instanceof Model) { @@ -238,13 +238,13 @@ protected function jsExecute($return, Model\UserAction $action) return $this->jsModelReturn($action, $msg); } - return $this->getNotifier($action, $this->defaultMsg); + return $this->jsCreateNotifier($action, $this->defaultMsg); } /** * Override this method for setting notifier based on action or model value. */ - protected function getNotifier(Model\UserAction $action, string $msg = null): JsExpressionable + protected function jsCreateNotifier(Model\UserAction $action, string $msg = null): JsExpressionable { $notifier = Factory::factory($this->notifyDefault); if ($msg) { @@ -262,7 +262,7 @@ protected function getNotifier(Model\UserAction $action, string $msg = null): Js protected function jsModelReturn(Model\UserAction $action, string $msg = 'Done!'): array { $js = []; - $js[] = $this->getNotifier($action, $msg); + $js[] = $this->jsCreateNotifier($action, $msg); $card = $action->getEntity()->isLoaded() ? $this->findCard($action->getEntity()) : null; if ($card !== null) { $js[] = $card->jsReload($this->getReloadArgs()); diff --git a/src/Crud.php b/src/Crud.php index 49b0e2a942..a53b93ce6f 100644 --- a/src/Crud.php +++ b/src/Crud.php @@ -175,14 +175,14 @@ protected function jsExecute($return, Model\UserAction $action): array // display msg return by action or depending on action modifier. if (is_string($return)) { - $js[] = $this->getNotifier($return); + $js[] = $this->jsCreateNotifier($return); } else { if ($action->modifier === Model\UserAction::MODIFIER_CREATE || $action->modifier === Model\UserAction::MODIFIER_UPDATE) { - $js[] = $this->getNotifier($this->saveMsg); + $js[] = $this->jsCreateNotifier($this->saveMsg); } elseif ($action->modifier === Model\UserAction::MODIFIER_DELETE) { - $js[] = $this->getNotifier($this->deleteMsg); + $js[] = $this->jsCreateNotifier($this->deleteMsg); } else { - $js[] = $this->getNotifier($this->defaultMsg); + $js[] = $this->jsCreateNotifier($this->defaultMsg); } } @@ -216,14 +216,9 @@ protected function getJsGridAction(Model\UserAction $action): ?JsExpressionable } /** - * Return jsNotifier object. * Override this method for setting notifier based on action or model value. - * - * @param string|null $msg the message to display - * - * @return JsExpressionable */ - protected function getNotifier(string $msg = null) + protected function jsCreateNotifier(string $msg = null): JsExpressionable { $notifier = Factory::factory($this->notifyDefault); if ($msg) { diff --git a/src/Form.php b/src/Form.php index 264ea5b8f0..34a9cb1c6b 100644 --- a/src/Form.php +++ b/src/Form.php @@ -15,6 +15,7 @@ use Atk4\Ui\Js\JsChain; use Atk4\Ui\Js\JsConditionalForm; use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; class Form extends View { @@ -289,19 +290,18 @@ public function getControl(string $name): Control /** * Causes form to generate error. * - * @param string $fieldName Field name - * @param string $str Error message + * @param string $errorMessage * * @return JsChain|array */ - public function error($fieldName, $str) + public function error(string $fieldName, $errorMessage) { // by using this hook you can overwrite default behavior of this method if ($this->hookHasCallbacks(self::HOOK_DISPLAY_ERROR)) { - return $this->hook(self::HOOK_DISPLAY_ERROR, [$fieldName, $str]); + return $this->hook(self::HOOK_DISPLAY_ERROR, [$fieldName, $errorMessage]); } - $jsError = [$this->js()->form('add prompt', $fieldName, $str)]; + $jsError = [$this->js()->form('add prompt', $fieldName, $errorMessage)]; return $jsError; } @@ -315,7 +315,7 @@ public function error($fieldName, $str) * * @return JsChain */ - public function success($success = 'Success', $subHeader = null, $useTemplate = true) + public function success($success = 'Success', $subHeader = null, bool $useTemplate = true) { $response = null; // by using this hook you can overwrite default behavior of this method @@ -391,7 +391,7 @@ public function addGroup($title = null) * * @return Jquery */ - public function jsInput($name) + public function jsInput($name): JsExpressionable { return $this->layout->getControl($name)->js()->find('input'); } diff --git a/src/Form/Control.php b/src/Form/Control.php index 0cda391390..03cd7dd652 100644 --- a/src/Form/Control.php +++ b/src/Form/Control.php @@ -166,7 +166,7 @@ public function onChange($expr, $defaults = []): void * * @return Jquery */ - public function jsInput($when = false, $action = null) + public function jsInput($when = false, $action = null): JsExpressionable { return $this->js($when, $action, '#' . $this->name . '_input'); } diff --git a/src/Form/Control/Checkbox.php b/src/Form/Control/Checkbox.php index 98b08bf4f6..518581a37d 100644 --- a/src/Form/Control/Checkbox.php +++ b/src/Form/Control/Checkbox.php @@ -89,7 +89,7 @@ protected function renderView(): void * * @return Jquery */ - public function jsChecked($when = false, $action = null) + public function jsChecked($when = false, $action = null): JsExpressionable { return $this->jsInput($when, $action)->get(0)->checked; } diff --git a/src/Grid.php b/src/Grid.php index 3e080b7acb..1f58ace050 100644 --- a/src/Grid.php +++ b/src/Grid.php @@ -9,7 +9,6 @@ use Atk4\Data\Field; use Atk4\Data\Model; use Atk4\Ui\Js\Jquery; -use Atk4\Ui\Js\JsExpression; use Atk4\Ui\Js\JsExpressionable; use Atk4\Ui\Js\JsReload; use Atk4\Ui\UserAction\ConfirmationExecutor; @@ -352,16 +351,7 @@ public function addQuickSearch($fields = [], $hasAutoQuery = false): void $this->quickSearch->initValue = $q; } - /** - * Returns JS for reloading View. - * - * @param array $args - * @param JsExpression|null $afterSuccess - * @param array $apiConfig - * - * @return JsReload - */ - public function jsReload($args = [], $afterSuccess = null, $apiConfig = []) + public function jsReload($args = [], $afterSuccess = null, $apiConfig = []): JsExpressionable { return new JsReload($this->container, $args, $afterSuccess, $apiConfig); } @@ -687,7 +677,7 @@ protected function recursiveRender(): void * * @return Jquery */ - public function jsRow() + public function jsRow(): JsExpressionable { return $this->table->jsRow(); } diff --git a/src/HtmlTemplate.php b/src/HtmlTemplate.php index e2b27f3ab3..0a3a2480d4 100644 --- a/src/HtmlTemplate.php +++ b/src/HtmlTemplate.php @@ -64,7 +64,7 @@ public function hasTag($tag): bool public function getTagTree(string $tag): TagTree { if (!isset($this->tagTrees[$tag])) { - throw (new Exception('Tag not found in template')) + throw (new Exception('Tag is not defined in template')) ->addMoreInfo('tag', $tag) ->addMoreInfo('template_tags', array_diff(array_keys($this->tagTrees), [self::TOP_TAG])); } diff --git a/src/Js/JsExpression.php b/src/Js/JsExpression.php index bd1a40cb32..f424d02b64 100644 --- a/src/Js/JsExpression.php +++ b/src/Js/JsExpression.php @@ -42,7 +42,7 @@ function ($matches) use (&$namelessCount): string { } if (!isset($this->args[$identifier])) { - throw (new Exception('Tag not defined in template for JsExpression')) + throw (new Exception('Tag is not defined in template')) ->addMoreInfo('tag', $identifier) ->addMoreInfo('template', $this->template); } diff --git a/src/Js/JsFunction.php b/src/Js/JsFunction.php index 6c2d1325f7..1b16d775d4 100644 --- a/src/Js/JsFunction.php +++ b/src/Js/JsFunction.php @@ -13,20 +13,20 @@ class JsFunction implements JsExpressionable { use WarnDynamicPropertyTrait; - /** @var array */ - public $args; + /** @var list */ + public array $args; /** @var array */ - public $statements = []; + public array $statements; - /** @var bool add preventDefault(event) to generated method */ - public $preventDefault = false; + /** Add event.preventDefault() to generated method */ + public bool $preventDefault = false; - /** @var bool add stopPropagation(event) to generated method */ - public $stopPropagation = false; + /** Add event.stopPropagation() to generated method */ + public bool $stopPropagation = false; - /** @var string Indent of target code (not one indent level) */ - public $indent = ' '; + /** Indent of target code (not one indent level) */ + public string $indent = ' '; /** * @param array|array $statements @@ -35,6 +35,7 @@ public function __construct(array $args, array $statements) { $this->args = $args; + $this->statements = []; foreach ($statements as $key => $value) { if (is_int($key)) { if ($value === null) { // TODO this should be not needed diff --git a/src/Js/JsReload.php b/src/Js/JsReload.php index b6f9cde8f0..2f72c5e05a 100644 --- a/src/Js/JsReload.php +++ b/src/Js/JsReload.php @@ -17,7 +17,7 @@ class JsReload implements JsExpressionable /** Specifies which view to reload. Use constructor to set. */ public View $view; - /** @var JsExpression|null A Js function to execute after reload is complete and onSuccess is execute. */ + /** @var JsExpressionable|null A Js function to execute after reload is complete and onSuccess is execute. */ public $afterSuccess; /** @var array Added at the end of your URL. */ @@ -32,7 +32,7 @@ class JsReload implements JsExpressionable /** @var bool */ public $includeStorage = false; - public function __construct(View $view, array $args = [], JsExpression $afterSuccess = null, array $apiConfig = [], bool $includeStorage = false) + public function __construct(View $view, array $args = [], JsExpressionable $afterSuccess = null, array $apiConfig = [], bool $includeStorage = false) { $this->view = $view; $this->args = $args; diff --git a/src/JsCallback.php b/src/JsCallback.php index 0caf27a8c9..53a8b607ac 100644 --- a/src/JsCallback.php +++ b/src/JsCallback.php @@ -96,6 +96,7 @@ public function set($fx = null, $args = null) $values[] = $_POST[$key] ?? null; } + /** @var JsExpressionable|View|string|list|null */ $response = $fx($chain, ...$values); if (count($chain->_chain) === 0) { @@ -137,8 +138,8 @@ public function terminateAjax($ajaxec, $msg = null, bool $success = true): void /** * Provided with a $response from callbacks convert it into a JavaScript code. * - * @param array|JsExpressionable $response response from callbacks, - * @param JsChain $chain + * @param JsExpressionable|View|string|list|null $response response from callbacks, + * @param JsChain $chain */ public function getAjaxec($response, $chain = null): string { diff --git a/src/JsPaginator.php b/src/JsPaginator.php index c910ef7366..c99951fe55 100644 --- a/src/JsPaginator.php +++ b/src/JsPaginator.php @@ -5,6 +5,7 @@ namespace Atk4\Ui; use Atk4\Ui\Js\Jquery; +use Atk4\Ui\Js\JsExpressionable; /** * Paginate content using scroll event in JS. @@ -46,11 +47,11 @@ protected function init(): void } /** - * Set jsPagiantor in idle mode. + * Set JsPaginator in idle mode. * * @return Jquery */ - public function jsIdle() + public function jsIdle(): JsExpressionable { return $this->view->js(true)->atkScroll('idle'); } diff --git a/src/JsSortable.php b/src/JsSortable.php index 8a7abb8761..66214e7619 100644 --- a/src/JsSortable.php +++ b/src/JsSortable.php @@ -5,6 +5,7 @@ namespace Atk4\Ui; use Atk4\Ui\Js\JsChain; +use Atk4\Ui\Js\JsExpressionable; class JsSortable extends JsCallback { @@ -82,7 +83,7 @@ public function onReorder(\Closure $fx): void * * @return JsChain */ - public function jsSendSortOrders($urlOptions = null) + public function jsSendSortOrders($urlOptions = null): JsExpressionable { return $this->view->js()->atkJsSortable('sendSortOrders', [$urlOptions]); } diff --git a/src/Loader.php b/src/Loader.php index b5ee6d56b1..d5665291ec 100644 --- a/src/Loader.php +++ b/src/Loader.php @@ -5,6 +5,7 @@ namespace Atk4\Ui; use Atk4\Ui\Js\JsChain; +use Atk4\Ui\Js\JsExpressionable; /** * Dynamically render it's content. @@ -111,7 +112,7 @@ protected function renderView(): void * * @return JsChain */ - public function jsLoad(array $args = [], array $apiConfig = [], $storeName = null) + public function jsLoad(array $args = [], array $apiConfig = [], $storeName = null): JsExpressionable { return $this->js()->atkReloadView([ 'url' => $this->cb->getUrl(), diff --git a/src/Modal.php b/src/Modal.php index b5b8d54327..3653c6b4f7 100644 --- a/src/Modal.php +++ b/src/Modal.php @@ -131,7 +131,7 @@ public function addContentCss($class): void * * @return JsChain */ - public function jsShow(array $args = []) + public function jsShow(array $args = []): JsExpressionable { $chain = $this->js(); if ($args !== []) { @@ -146,7 +146,7 @@ public function jsShow(array $args = []) * * @return JsChain */ - public function jsHide() + public function jsHide(): JsExpressionable { return $this->js()->modal('hide'); } @@ -182,11 +182,11 @@ public function addScrolling() * Add a deny action to modal. * * @param string $label - * @param JsExpressionable $jsAction javascript action that will run when deny is click + * @param JsExpressionable $jsAction will run when deny is click * * @return $this */ - public function addDenyAction($label, $jsAction) + public function addDenyAction($label, JsExpressionable $jsAction) { $button = new Button(); $button->set($label)->addClass('red cancel'); @@ -200,11 +200,11 @@ public function addDenyAction($label, $jsAction) * Add an approve action button to modal. * * @param string $label - * @param JsExpressionable $jsAction javascript action that will run when deny is click + * @param JsExpressionable $jsAction will run when deny is click * * @return $this */ - public function addApproveAction($label, $jsAction) + public function addApproveAction($label, JsExpressionable $jsAction) { $b = new Button(); $b->set($label)->addClass('green ok'); diff --git a/src/Panel/Right.php b/src/Panel/Right.php index b46de9ca4e..db01eadddf 100644 --- a/src/Panel/Right.php +++ b/src/Panel/Right.php @@ -8,7 +8,7 @@ use Atk4\Ui\Button; use Atk4\Ui\Js\Jquery; use Atk4\Ui\Js\JsChain; -use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; use Atk4\Ui\Modal; use Atk4\Ui\View; @@ -95,12 +95,12 @@ public function service(): JsChain /** * Return js expression need to open panel via js panelService. * - * @param array $urlArgs the argument to include when dynamic content panel open - * @param array $dataAttribute the data attribute name to include in reload from the triggering element - * @param string|null $activeCss the css class name to apply on triggering element when panel is open - * @param JsExpression $jsTrigger JsExpression that trigger panel to open. Default = $(this). + * @param array $urlArgs the argument to include when dynamic content panel open + * @param array $dataAttribute the data attribute name to include in reload from the triggering element + * @param string|null $activeCss the css class name to apply on triggering element when panel is open + * @param JsExpressionable $jsTrigger JS expression that trigger panel to open. Default = $(this). */ - public function jsOpen(array $urlArgs = [], array $dataAttribute = [], string $activeCss = null, JsExpression $jsTrigger = null): JsExpression + public function jsOpen(array $urlArgs = [], array $dataAttribute = [], string $activeCss = null, JsExpressionable $jsTrigger = null): JsExpressionable { return $this->service()->openPanel([ 'triggered' => $jsTrigger ?? new Jquery(), @@ -114,7 +114,7 @@ public function jsOpen(array $urlArgs = [], array $dataAttribute = [], string $a /** * Will reload panel passing args as Get param via js flyoutService. */ - public function jsPanelReload(array $args = []): JsExpression + public function jsPanelReload(array $args = []): JsExpressionable { return $this->service()->reloadPanel($this->name, $args); } @@ -122,7 +122,7 @@ public function jsPanelReload(array $args = []): JsExpression /** * Return js expression need to close panel via js panelService. */ - public function jsClose(): JsExpression + public function jsClose(): JsExpressionable { return $this->service()->closePanel($this->name); } @@ -163,7 +163,7 @@ public function onOpen(\Closure $callback): void * * @return Jquery */ - public function jsDisplayWarning(bool $state = true): JsExpression + public function jsDisplayWarning(bool $state = true): JsExpressionable { $chain = new Jquery('#' . $this->name . ' ' . $this->warningSelector); @@ -175,7 +175,7 @@ public function jsDisplayWarning(bool $state = true): JsExpression * * @return Jquery */ - public function jsToggleWarning(): JsExpression + public function jsToggleWarning(): JsExpressionable { return (new Jquery('#' . $this->name . ' ' . $this->warningSelector))->toggleClass($this->warningTrigger); } diff --git a/src/Popup.php b/src/Popup.php index 9e9be13b2b..f4449907fa 100644 --- a/src/Popup.php +++ b/src/Popup.php @@ -6,6 +6,7 @@ use Atk4\Ui\Js\Jquery; use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; /** * Implement popup view. @@ -215,7 +216,7 @@ public function setOption(string $name, $option) * * @return Jquery */ - public function jsPopup() + public function jsPopup(): JsExpressionable { $selector = $this->triggerBy; if ($this->triggerBy instanceof Form\Control) { diff --git a/src/ProgressBar.php b/src/ProgressBar.php index 1c16d957ae..cbc1416d2e 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -48,20 +48,16 @@ protected function renderView(): void /** * Return js action for incrementing progress by one. - * - * @return JsExpressionable */ - public function jsIncrement() + public function jsIncrement(): JsExpressionable { return $this->js()->progress('increment'); } /** * Return js action for setting value (client-side). - * - * @return JsExpressionable */ - public function jsValue(int $value) + public function jsValue(int $value): JsExpressionable { return $this->js()->progress(['percent' => $value]); } diff --git a/src/Table.php b/src/Table.php index 20627e5d8c..cc66f9f75f 100644 --- a/src/Table.php +++ b/src/Table.php @@ -536,7 +536,7 @@ public function onRowClick($action): void * * @return Jquery */ - public function jsRow() + public function jsRow(): JsExpressionable { return (new Jquery())->closest('tr'); } @@ -549,7 +549,7 @@ public function jsRow() * * @return Jquery */ - public function jsRemoveRow($id, $transition = 'fade left') + public function jsRemoveRow($id, $transition = 'fade left'): JsExpressionable { return $this->js()->find('tr[data-id=' . $id . ']')->transition($transition); } diff --git a/src/Table/Column.php b/src/Table/Column.php index dc47b7c693..eecaf5e46c 100644 --- a/src/Table/Column.php +++ b/src/Table/Column.php @@ -147,11 +147,11 @@ public function addDropdown(array $items, \Closure $fx, $icon = 'caret square do * This method return a callback where you can detect * menu item change via $cb->onMenuItem($item) function. * - * @param array $items + * @param array $items * - * @return JsCallback + * @return Column\JsHeader */ - public function setHeaderDropdown($items, string $icon = 'caret square down', string $menuId = null) + public function setHeaderDropdown($items, string $icon = 'caret square down', string $menuId = null): JsCallback { $this->hasHeaderAction = true; $id = $this->name . '_ac'; diff --git a/src/Table/Column/ActionButtons.php b/src/Table/Column/ActionButtons.php index 0aa44caeb5..9820362c31 100644 --- a/src/Table/Column/ActionButtons.php +++ b/src/Table/Column/ActionButtons.php @@ -35,8 +35,6 @@ protected function init(): void /** * Adds a new button which will execute $callback when clicked. * - * Returns button object - * * @param string|array|View $button * @param JsChain|\Closure|ExecutorInterface $action * @param bool|\Closure $isDisabled diff --git a/src/Table/Column/Checkbox.php b/src/Table/Column/Checkbox.php index d1ca6efb5d..1f134a19fa 100644 --- a/src/Table/Column/Checkbox.php +++ b/src/Table/Column/Checkbox.php @@ -8,6 +8,7 @@ use Atk4\Ui\Exception; use Atk4\Ui\Js\Jquery; use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; use Atk4\Ui\Table; /** @@ -22,10 +23,8 @@ class Checkbox extends Table\Column * Return action which will calculate and return array of all Checkbox IDs, e.g. * * [3, 5, 20] - * - * @return JsExpression */ - public function jsChecked() + public function jsChecked(): JsExpressionable { return (new Jquery($this->table))->find('.checked.' . $this->class)->closest('tr') ->map(new \Atk4\Ui\Js\JsFunction([], [new JsExpression('return $(this).data(\'id\')')])) diff --git a/src/UserAction/BasicExecutor.php b/src/UserAction/BasicExecutor.php index d5f3e6e69d..b43d91ece0 100644 --- a/src/UserAction/BasicExecutor.php +++ b/src/UserAction/BasicExecutor.php @@ -44,7 +44,7 @@ class BasicExecutor extends View implements ExecutorInterface /** @var array list of validated arguments */ protected $validArguments = []; - /** @var JsExpressionable|\Closure JsExpression to return if action was successful, e.g "new JsToast('Thank you')" */ + /** @var JsExpressionable|\Closure JS expression to return if action was successful, e.g "new JsToast('Thank you')" */ protected $jsSuccess; public function getAction(): Model\UserAction diff --git a/src/UserAction/ConfirmationExecutor.php b/src/UserAction/ConfirmationExecutor.php index 6e6517b1b4..abcccec92d 100644 --- a/src/UserAction/ConfirmationExecutor.php +++ b/src/UserAction/ConfirmationExecutor.php @@ -35,7 +35,7 @@ class ConfirmationExecutor extends Modal implements JsExecutorInterface public $loaderUi = 'basic segment'; /** @var array|View|null Loader shim object or seed. */ public $loaderShim; - /** @var JsExpressionable|\Closure JsExpression to return if action was successful, e.g "new JsToast('Thank you')" */ + /** @var JsExpressionable|\Closure JS expression to return if action was successful, e.g "new JsToast('Thank you')" */ public $jsSuccess; /** @var string css class for modal size. */ diff --git a/src/UserAction/JsCallbackExecutor.php b/src/UserAction/JsCallbackExecutor.php index f68cabf4e3..9bd3439bbd 100644 --- a/src/UserAction/JsCallbackExecutor.php +++ b/src/UserAction/JsCallbackExecutor.php @@ -34,7 +34,7 @@ class JsCallbackExecutor extends JsCallback implements ExecutorInterface /** @var Model\UserAction The model user action */ public $action; - /** @var JsExpressionable|\Closure JsExpression to return if action was successful, e.g "new JsToast('Thank you')" */ + /** @var JsExpressionable|\Closure JS expression to return if action was successful, e.g "new JsToast('Thank you')" */ public $jsSuccess; public function getAction(): Model\UserAction diff --git a/src/UserAction/StepExecutorTrait.php b/src/UserAction/StepExecutorTrait.php index fc8e13e661..e1b51ac168 100644 --- a/src/UserAction/StepExecutorTrait.php +++ b/src/UserAction/StepExecutorTrait.php @@ -54,7 +54,7 @@ trait StepExecutorTrait /** @var bool */ protected $actionInitialized = false; - /** @var JsExpressionable|\Closure JsExpression to return if action was successful, e.g "new JsToast('Thank you')" */ + /** @var JsExpressionable|\Closure JS expression to return if action was successful, e.g "new JsToast('Thank you')" */ public $jsSuccess; /** @var array A seed for creating form in order to edit arguments/fields user entry. */ diff --git a/src/View.php b/src/View.php index 91526a2b07..84dc32f76a 100644 --- a/src/View.php +++ b/src/View.php @@ -867,10 +867,8 @@ public function jsEmitEvent(string $eventName, array $eventData = []): JsChain /** * Get Local and Session web storage associated with this view. * Web storage can be retrieved using a $view->jsReload() request. - * - * @return mixed */ - public function jsGetStoreData() + public function jsGetStoreData(): array { $data = []; $data['local'] = $this->getApp()->decodeJson($_GET[$this->name . '_local_store'] ?? $_POST[$this->name . '_local_store'] ?? 'null'); @@ -881,10 +879,8 @@ public function jsGetStoreData() /** * Clear Web storage data associated with this view. - * - * @return mixed */ - public function jsClearStoreData(bool $useSession = false) + public function jsClearStoreData(bool $useSession = false): JsExpressionable { $type = $useSession ? 'session' : 'local'; @@ -906,10 +902,8 @@ public function jsClearStoreData(bool $useSession = false) * $v->jsAddStoreData(['args' => ['path' => '/'], 'fields' => ['name' => 'test']]]); * * Final store value will be: ['args' => ['path' => '/'], 'fields' => ['name' => 'test']]; - * - * @return mixed */ - public function jsAddStoreData(array $data, bool $useSession = false) + public function jsAddStoreData(array $data, bool $useSession = false): JsExpressionable { $type = $useSession ? 'session' : 'local'; @@ -924,13 +918,13 @@ public function jsAddStoreData(array $data, bool $useSession = false) /** * Returns JS for reloading View. * - * @param array $args - * @param JsExpression|null $afterSuccess - * @param array $apiConfig + * @param array $args + * @param JsExpressionable|null $afterSuccess + * @param array $apiConfig * * @return JsReload */ - public function jsReload($args = [], $afterSuccess = null, $apiConfig = []) + public function jsReload($args = [], $afterSuccess = null, $apiConfig = []): JsExpressionable { return new JsReload($this, $args, $afterSuccess, $apiConfig); } diff --git a/src/VueComponent/InlineEdit.php b/src/VueComponent/InlineEdit.php index f4e19c9b27..646ae6780e 100644 --- a/src/VueComponent/InlineEdit.php +++ b/src/VueComponent/InlineEdit.php @@ -7,6 +7,7 @@ use Atk4\Data\Model; use Atk4\Data\ValidationException; use Atk4\Ui\Exception; +use Atk4\Ui\Js\JsExpressionable; use Atk4\Ui\Js\JsToast; use Atk4\Ui\JsCallback; use Atk4\Ui\View; @@ -133,7 +134,7 @@ public function onChange(\Closure $fx): void * * @return JsToast */ - public function jsSuccess(string $message) + public function jsSuccess(string $message): JsExpressionable { return new JsToast([ 'title' => 'Success', @@ -149,7 +150,7 @@ public function jsSuccess(string $message) * * @return JsToast */ - public function jsError($message) + public function jsError($message): JsExpressionable { return new JsToast([ 'title' => 'Validation error:', diff --git a/src/Wizard.php b/src/Wizard.php index 1f02f8499b..966748219f 100644 --- a/src/Wizard.php +++ b/src/Wizard.php @@ -6,6 +6,7 @@ use Atk4\Core\Factory; use Atk4\Ui\Js\JsExpression; +use Atk4\Ui\Js\JsExpressionable; class Wizard extends View { @@ -143,7 +144,7 @@ public function add($seed, $region = null): AbstractView } /** - * Get URL to next step. Will respect stickyGET. + * Get URL to next step. Will respect stickyGet. */ public function urlNext(): string { @@ -151,11 +152,9 @@ public function urlNext(): string } /** - * Generate a js that will navigate to next step URL. - * - * @return JsExpression + * Generate JS that will navigate to next step URL. */ - public function jsNext() + public function jsNext(): JsExpressionable { return new JsExpression('document.location = []', [$this->urlNext()]); }