Skip to content

Commit 4d668bd

Browse files
Merge pull request #19193 from MauricioFauth/config-inline-params-script-extraction
Extract config inline params JS from config/form_display/display.twig
2 parents 40fdced + e03642b commit 4d668bd

7 files changed

Lines changed: 83 additions & 63 deletions

File tree

psalm-baseline.xml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@
481481
$workPath,
482482
$translatedPath,
483483
$userPrefsAllow,
484-
$jsDefault,
484+
$defaultValues,
485485
)]]></code>
486486
</PossiblyNullOperand>
487487
<RiskyTruthyFalsyComparison>
@@ -499,9 +499,6 @@
499499
<code><![CDATA[$vName]]></code>
500500
<code><![CDATA[$validator]]></code>
501501
</MixedAssignment>
502-
<MixedOperand>
503-
<code><![CDATA[$vName]]></code>
504-
</MixedOperand>
505502
<RiskyTruthyFalsyComparison>
506503
<code><![CDATA[! $isSetupScript]]></code>
507504
<code><![CDATA[$this->config->get('is_setup')]]></code>

resources/js/src/modules/config.ts

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { ajaxShowMessage } from './ajax-message.ts';
44
import isStorageSupported from './functions/isStorageSupported.ts';
55
import formatDateTime from './functions/formatDateTime.ts';
66

7-
window.configInlineParams;
8-
window.configScriptLoaded;
7+
let configInlineParams: any[] | undefined;
8+
let configScriptLoaded: boolean = false;
99

1010
// default values for fields
11-
window.defaultValues = {};
11+
const defaultValues: object = {};
1212

1313
/**
1414
* Returns field type
@@ -170,21 +170,21 @@ function getAllValues () {
170170
function checkFieldDefault (field, type) {
171171
var $field = $(field);
172172
var fieldId = $field.attr('id');
173-
if (typeof window.defaultValues[fieldId] === 'undefined') {
173+
if (typeof defaultValues[fieldId] === 'undefined') {
174174
return true;
175175
}
176176

177177
var isDefault = true;
178178
var currentValue = getFieldValue($field, type);
179179
if (type !== 'select') {
180-
isDefault = currentValue === window.defaultValues[fieldId];
180+
isDefault = currentValue === defaultValues[fieldId];
181181
} else {
182182
// compare arrays, will work for our representation of select values
183-
if (currentValue.length !== window.defaultValues[fieldId].length) {
183+
if (currentValue.length !== defaultValues[fieldId].length) {
184184
isDefault = false;
185185
} else {
186186
for (var i = 0; i < currentValue.length; i++) {
187-
if (currentValue[i] !== window.defaultValues[fieldId][i]) {
187+
if (currentValue[i] !== defaultValues[fieldId][i]) {
188188
isDefault = false;
189189
break;
190190
}
@@ -313,7 +313,7 @@ const validators = {
313313
* @param {boolean} onKeyUp whether fire on key up
314314
* @param {any[]} params validation function parameters
315315
*/
316-
function registerFieldValidator (id, type, onKeyUp, params) {
316+
function registerFieldValidator (id, type, onKeyUp, params = undefined) {
317317
if (typeof window.validators[type] === 'undefined') {
318318
return;
319319
}
@@ -509,21 +509,44 @@ function validateFieldAndFieldset (field, isKeyUp) {
509509
}
510510

511511
function loadInlineConfig () {
512-
if (! Array.isArray(window.configInlineParams)) {
512+
if (! Array.isArray(configInlineParams)) {
513513
return;
514514
}
515515

516-
for (var i = 0; i < window.configInlineParams.length; ++i) {
517-
if (typeof window.configInlineParams[i] === 'function') {
518-
window.configInlineParams[i]();
516+
for (var i = 0; i < configInlineParams.length; ++i) {
517+
if (typeof configInlineParams[i] === 'function') {
518+
configInlineParams[i]();
519519
}
520520
}
521521
}
522522

523523
function setupValidation () {
524524
validate = {};
525-
window.configScriptLoaded = true;
526-
if (window.configScriptLoaded && typeof window.configInlineParams !== 'undefined') {
525+
526+
const configInlineParamsData = $('#configInlineParamsData');
527+
if (configInlineParamsData.length > 0) {
528+
const fieldValidators = configInlineParamsData.data('fieldValidators');
529+
const inlineDefaultValues = configInlineParamsData.data('defaultValues');
530+
531+
if (typeof configInlineParams === 'undefined' || !Array.isArray(configInlineParams)) {
532+
configInlineParams = [];
533+
}
534+
535+
configInlineParams.push(function () {
536+
for (const validator of fieldValidators) {
537+
if (validator.args) {
538+
registerFieldValidator(validator.fieldId, validator.name, true, validator.args);
539+
} else {
540+
registerFieldValidator(validator.fieldId, validator.name, true);
541+
}
542+
}
543+
});
544+
545+
$.extend(defaultValues, inlineDefaultValues);
546+
}
547+
548+
configScriptLoaded = true;
549+
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
527550
Config.loadInlineConfig();
528551
}
529552

@@ -598,11 +621,11 @@ function adjustPrefsNotification () {
598621
*/
599622
function restoreField (fieldId): void {
600623
var $field = $('#' + fieldId);
601-
if ($field.length === 0 || window.defaultValues[fieldId] === undefined) {
624+
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
602625
return;
603626
}
604627

605-
setFieldValue($field, getFieldType($field), window.defaultValues[fieldId]);
628+
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
606629
}
607630

608631
function setupRestoreField () {
@@ -755,7 +778,7 @@ function on () {
755778
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
756779
var fields = $(this).closest('fieldset').find('input, select, textarea');
757780
for (var i = 0, imax = fields.length; i < imax; i++) {
758-
setFieldValue(fields[i], getFieldType(fields[i]), window.defaultValues[fields[i].id]);
781+
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
759782
}
760783

761784
setDisplayError();
@@ -833,7 +856,6 @@ function on () {
833856
const Config = {
834857
getAllValues: getAllValues,
835858
getIdPrefix: getIdPrefix,
836-
registerFieldValidator: registerFieldValidator,
837859
displayErrors: displayErrors,
838860
loadInlineConfig: loadInlineConfig,
839861
setupValidation: setupValidation,
@@ -844,9 +866,6 @@ const Config = {
844866

845867
declare global {
846868
interface Window {
847-
configInlineParams: any[] | undefined;
848-
configScriptLoaded: boolean | undefined;
849-
defaultValues: object;
850869
validators: typeof validators;
851870
Config: typeof Config;
852871
}

resources/templates/config/form_display/display.twig

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,6 @@
5353
</div>
5454
</form>
5555

56-
<script>
57-
if (typeof window.configInlineParams === 'undefined' || !Array.isArray(window.configInlineParams)) {
58-
window.configInlineParams = [];
59-
}
60-
window.configInlineParams.push(function () {
61-
{{ js_array|join(';\n')|raw }};
62-
63-
$.extend(window.defaultValues,
64-
{{ js_default|json_encode(constant('JSON_HEX_TAG'))|raw }}
65-
);
66-
});
67-
if (typeof window.configScriptLoaded !== 'undefined' && window.configInlineParams) {
68-
window.Config.loadInlineConfig();
69-
}
70-
</script>
56+
<span id="configInlineParamsData"
57+
data-field-validators="{{ field_validators|json_encode|e('html_attr') }}"
58+
data-default-values="{{ default_values|json_encode|e('html_attr') }}"></span>

src/Config/FormDisplay.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ public function getDisplay(
214214
string|null $formAction = null,
215215
array|null $hiddenFields = null,
216216
): string {
217-
$js = [];
218-
$jsDefault = [];
217+
$fieldValidators = [];
218+
$defaultValues = [];
219219

220220
/**
221221
* We do validation on page refresh when browser remembers field values,
@@ -278,14 +278,14 @@ public function getDisplay(
278278
$workPath,
279279
$translatedPath,
280280
$userPrefsAllow,
281-
$jsDefault,
281+
$defaultValues,
282282
);
283283
// register JS validators for this field
284284
if (! isset($validators[$path])) {
285285
continue;
286286
}
287287

288-
$this->formDisplayTemplate->addJsValidate($translatedPath, $validators[$path], $js);
288+
$this->formDisplayTemplate->addJsValidate($translatedPath, $validators[$path], $fieldValidators);
289289
}
290290
}
291291

@@ -296,8 +296,8 @@ public function getDisplay(
296296
'tabs' => $tabs,
297297
'forms' => $forms,
298298
'show_buttons' => $showButtons,
299-
'js_array' => $js,
300-
'js_default' => $jsDefault,
299+
'default_values' => $defaultValues,
300+
'field_validators' => $fieldValidators,
301301
]);
302302
}
303303

src/Config/FormDisplayTemplate.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
use PhpMyAdmin\Template;
1212

1313
use function array_shift;
14-
use function json_encode;
15-
16-
use const JSON_HEX_TAG;
1714

1815
/**
1916
* PhpMyAdmin\Config\FormDisplayTemplate class
@@ -127,18 +124,20 @@ public function displayGroupFooter(): void
127124
/**
128125
* Appends JS validation code to $js_array
129126
*
130-
* @param string $fieldId ID of field to validate
131-
* @param string|mixed[] $validators validators callback
132-
* @param mixed[] $jsArray will be updated with javascript code
127+
* @param string $fieldId ID of field to validate
128+
* @param string|mixed[] $validators validators callback
129+
* @param mixed[] $fieldValidators will be updated with javascript code
133130
*/
134-
public function addJsValidate(string $fieldId, string|array $validators, array &$jsArray): void
131+
public function addJsValidate(string $fieldId, string|array $validators, array &$fieldValidators): void
135132
{
136133
foreach ((array) $validators as $validator) {
137134
$validator = (array) $validator;
138135
$vName = array_shift($validator);
139-
$vArgs = $validator !== [] ? ', ' . json_encode($validator, JSON_HEX_TAG) : '';
140-
$jsArray[] = "window.Config.registerFieldValidator('"
141-
. $fieldId . "', '" . $vName . "', true" . $vArgs . ')';
136+
$fieldValidators[] = [
137+
'fieldId' => $fieldId,
138+
'name' => $vName,
139+
'args' => $validator !== [] ? $validator : null,
140+
];
142141
}
143142
}
144143

tests/unit/Config/FormDisplayTemplateTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,8 @@ public function testAddJsValidate(): void
242242

243243
self::assertSame(
244244
[
245-
'window.Config.registerFieldValidator(\'testID\', \'\\\';\', true, '
246-
. '["\\\\r\\\\n\\\\\''
247-
. '\u003CscrIpt\u003E\u003C\/\' + \'script\u003E"])',
248-
'window.Config.registerFieldValidator(\'testID\', \'\', true)',
245+
['fieldId' => 'testID', 'name' => '\\\';', 'args' => ['\r\n\\\'<scrIpt></\' + \'script>']],
246+
['fieldId' => 'testID', 'name' => null, 'args' => null],
249247
],
250248
$js,
251249
);

tests/unit/Config/PageSettingsTest.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,28 @@ public function testShowGroupBrowse(): void
7979
self::assertStringContainsString('<input type="hidden" name="submit_save" value="Browse">', $html);
8080

8181
self::assertStringContainsString(
82-
"window.Config.registerFieldValidator('MaxRows', 'validatePositiveNumber', true);\n"
83-
. "window.Config.registerFieldValidator('RepeatCells', 'validateNonNegativeNumber', true);\n"
84-
. "window.Config.registerFieldValidator('LimitChars', 'validatePositiveNumber', true);\n",
82+
'data-field-validators="&#x5B;&#x7B;&quot;fieldId&quot;&#x3A;&quot;MaxRows&quot;,'
83+
. '&quot;name&quot;&#x3A;&quot;validatePositiveNumber&quot;,'
84+
. '&quot;args&quot;&#x3A;null&#x7D;,&#x7B;&quot;fieldId&quot;&#x3A;&quot;RepeatCells&quot;,'
85+
. '&quot;name&quot;&#x3A;&quot;validateNonNegativeNumber&quot;,'
86+
. '&quot;args&quot;&#x3A;null&#x7D;,&#x7B;&quot;fieldId&quot;&#x3A;&quot;LimitChars&quot;,'
87+
. '&quot;name&quot;&#x3A;&quot;validatePositiveNumber&quot;,&quot;args&quot;&#x3A;null&#x7D;&#x5D;"',
88+
$html,
89+
);
90+
self::assertStringContainsString(
91+
'data-default-values="&#x7B;&quot;TableNavigationLinksMode&quot;&#x3A;&#x5B;&quot;icons&quot;&#x5D;,'
92+
. '&quot;ActionLinksMode&quot;&#x3A;&#x5B;&quot;both&quot;&#x5D;,'
93+
. '&quot;ShowAll&quot;&#x3A;false,&quot;MaxRows&quot;&#x3A;&#x5B;25&#x5D;,'
94+
. '&quot;Order&quot;&#x3A;&#x5B;&quot;SMART&quot;&#x5D;,'
95+
. '&quot;BrowsePointerEnable&quot;&#x3A;true,&quot;BrowseMarkerEnable&quot;&#x3A;true,'
96+
. '&quot;GridEditing&quot;&#x3A;&#x5B;&quot;double-click&quot;&#x5D;,'
97+
. '&quot;SaveCellsAtOnce&quot;&#x3A;false,&quot;RepeatCells&quot;&#x3A;&quot;100&quot;,'
98+
. '&quot;LimitChars&quot;&#x3A;&quot;50&quot;,'
99+
. '&quot;RowActionLinks&quot;&#x3A;&#x5B;&quot;left&quot;&#x5D;,'
100+
. '&quot;RowActionLinksWithoutUnique&quot;&#x3A;false,'
101+
. '&quot;TablePrimaryKeyOrder&quot;&#x3A;&#x5B;&quot;NONE&quot;&#x5D;,'
102+
. '&quot;RememberSorting&quot;&#x3A;true,'
103+
. '&quot;RelationalDisplay&quot;&#x3A;&#x5B;&quot;K&quot;&#x5D;&#x7D;"',
85104
$html,
86105
);
87106
}

0 commit comments

Comments
 (0)