Merge pull request #19193 from MauricioFauth/config-inline-params-script-extraction
Extract config inline params JS from config/form_display/display.twig
This commit is contained in:
commit
4d668bd365
@ -481,7 +481,7 @@
|
||||
$workPath,
|
||||
$translatedPath,
|
||||
$userPrefsAllow,
|
||||
$jsDefault,
|
||||
$defaultValues,
|
||||
)]]></code>
|
||||
</PossiblyNullOperand>
|
||||
<RiskyTruthyFalsyComparison>
|
||||
@ -499,9 +499,6 @@
|
||||
<code><![CDATA[$vName]]></code>
|
||||
<code><![CDATA[$validator]]></code>
|
||||
</MixedAssignment>
|
||||
<MixedOperand>
|
||||
<code><![CDATA[$vName]]></code>
|
||||
</MixedOperand>
|
||||
<RiskyTruthyFalsyComparison>
|
||||
<code><![CDATA[! $isSetupScript]]></code>
|
||||
<code><![CDATA[$this->config->get('is_setup')]]></code>
|
||||
|
||||
@ -4,11 +4,11 @@ import { ajaxShowMessage } from './ajax-message.ts';
|
||||
import isStorageSupported from './functions/isStorageSupported.ts';
|
||||
import formatDateTime from './functions/formatDateTime.ts';
|
||||
|
||||
window.configInlineParams;
|
||||
window.configScriptLoaded;
|
||||
let configInlineParams: any[] | undefined;
|
||||
let configScriptLoaded: boolean = false;
|
||||
|
||||
// default values for fields
|
||||
window.defaultValues = {};
|
||||
const defaultValues: object = {};
|
||||
|
||||
/**
|
||||
* Returns field type
|
||||
@ -170,21 +170,21 @@ function getAllValues () {
|
||||
function checkFieldDefault (field, type) {
|
||||
var $field = $(field);
|
||||
var fieldId = $field.attr('id');
|
||||
if (typeof window.defaultValues[fieldId] === 'undefined') {
|
||||
if (typeof defaultValues[fieldId] === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
|
||||
var isDefault = true;
|
||||
var currentValue = getFieldValue($field, type);
|
||||
if (type !== 'select') {
|
||||
isDefault = currentValue === window.defaultValues[fieldId];
|
||||
isDefault = currentValue === defaultValues[fieldId];
|
||||
} else {
|
||||
// compare arrays, will work for our representation of select values
|
||||
if (currentValue.length !== window.defaultValues[fieldId].length) {
|
||||
if (currentValue.length !== defaultValues[fieldId].length) {
|
||||
isDefault = false;
|
||||
} else {
|
||||
for (var i = 0; i < currentValue.length; i++) {
|
||||
if (currentValue[i] !== window.defaultValues[fieldId][i]) {
|
||||
if (currentValue[i] !== defaultValues[fieldId][i]) {
|
||||
isDefault = false;
|
||||
break;
|
||||
}
|
||||
@ -313,7 +313,7 @@ const validators = {
|
||||
* @param {boolean} onKeyUp whether fire on key up
|
||||
* @param {any[]} params validation function parameters
|
||||
*/
|
||||
function registerFieldValidator (id, type, onKeyUp, params) {
|
||||
function registerFieldValidator (id, type, onKeyUp, params = undefined) {
|
||||
if (typeof window.validators[type] === 'undefined') {
|
||||
return;
|
||||
}
|
||||
@ -509,21 +509,44 @@ function validateFieldAndFieldset (field, isKeyUp) {
|
||||
}
|
||||
|
||||
function loadInlineConfig () {
|
||||
if (! Array.isArray(window.configInlineParams)) {
|
||||
if (! Array.isArray(configInlineParams)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < window.configInlineParams.length; ++i) {
|
||||
if (typeof window.configInlineParams[i] === 'function') {
|
||||
window.configInlineParams[i]();
|
||||
for (var i = 0; i < configInlineParams.length; ++i) {
|
||||
if (typeof configInlineParams[i] === 'function') {
|
||||
configInlineParams[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupValidation () {
|
||||
validate = {};
|
||||
window.configScriptLoaded = true;
|
||||
if (window.configScriptLoaded && typeof window.configInlineParams !== 'undefined') {
|
||||
|
||||
const configInlineParamsData = $('#configInlineParamsData');
|
||||
if (configInlineParamsData.length > 0) {
|
||||
const fieldValidators = configInlineParamsData.data('fieldValidators');
|
||||
const inlineDefaultValues = configInlineParamsData.data('defaultValues');
|
||||
|
||||
if (typeof configInlineParams === 'undefined' || !Array.isArray(configInlineParams)) {
|
||||
configInlineParams = [];
|
||||
}
|
||||
|
||||
configInlineParams.push(function () {
|
||||
for (const validator of fieldValidators) {
|
||||
if (validator.args) {
|
||||
registerFieldValidator(validator.fieldId, validator.name, true, validator.args);
|
||||
} else {
|
||||
registerFieldValidator(validator.fieldId, validator.name, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(defaultValues, inlineDefaultValues);
|
||||
}
|
||||
|
||||
configScriptLoaded = true;
|
||||
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
|
||||
Config.loadInlineConfig();
|
||||
}
|
||||
|
||||
@ -598,11 +621,11 @@ function adjustPrefsNotification () {
|
||||
*/
|
||||
function restoreField (fieldId): void {
|
||||
var $field = $('#' + fieldId);
|
||||
if ($field.length === 0 || window.defaultValues[fieldId] === undefined) {
|
||||
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFieldValue($field, getFieldType($field), window.defaultValues[fieldId]);
|
||||
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
|
||||
}
|
||||
|
||||
function setupRestoreField () {
|
||||
@ -755,7 +778,7 @@ function on () {
|
||||
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
|
||||
var fields = $(this).closest('fieldset').find('input, select, textarea');
|
||||
for (var i = 0, imax = fields.length; i < imax; i++) {
|
||||
setFieldValue(fields[i], getFieldType(fields[i]), window.defaultValues[fields[i].id]);
|
||||
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
|
||||
}
|
||||
|
||||
setDisplayError();
|
||||
@ -833,7 +856,6 @@ function on () {
|
||||
const Config = {
|
||||
getAllValues: getAllValues,
|
||||
getIdPrefix: getIdPrefix,
|
||||
registerFieldValidator: registerFieldValidator,
|
||||
displayErrors: displayErrors,
|
||||
loadInlineConfig: loadInlineConfig,
|
||||
setupValidation: setupValidation,
|
||||
@ -844,9 +866,6 @@ const Config = {
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
configInlineParams: any[] | undefined;
|
||||
configScriptLoaded: boolean | undefined;
|
||||
defaultValues: object;
|
||||
validators: typeof validators;
|
||||
Config: typeof Config;
|
||||
}
|
||||
|
||||
@ -53,18 +53,6 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
if (typeof window.configInlineParams === 'undefined' || !Array.isArray(window.configInlineParams)) {
|
||||
window.configInlineParams = [];
|
||||
}
|
||||
window.configInlineParams.push(function () {
|
||||
{{ js_array|join(';\n')|raw }};
|
||||
|
||||
$.extend(window.defaultValues,
|
||||
{{ js_default|json_encode(constant('JSON_HEX_TAG'))|raw }}
|
||||
);
|
||||
});
|
||||
if (typeof window.configScriptLoaded !== 'undefined' && window.configInlineParams) {
|
||||
window.Config.loadInlineConfig();
|
||||
}
|
||||
</script>
|
||||
<span id="configInlineParamsData"
|
||||
data-field-validators="{{ field_validators|json_encode|e('html_attr') }}"
|
||||
data-default-values="{{ default_values|json_encode|e('html_attr') }}"></span>
|
||||
|
||||
@ -214,8 +214,8 @@ class FormDisplay
|
||||
string|null $formAction = null,
|
||||
array|null $hiddenFields = null,
|
||||
): string {
|
||||
$js = [];
|
||||
$jsDefault = [];
|
||||
$fieldValidators = [];
|
||||
$defaultValues = [];
|
||||
|
||||
/**
|
||||
* We do validation on page refresh when browser remembers field values,
|
||||
@ -278,14 +278,14 @@ class FormDisplay
|
||||
$workPath,
|
||||
$translatedPath,
|
||||
$userPrefsAllow,
|
||||
$jsDefault,
|
||||
$defaultValues,
|
||||
);
|
||||
// register JS validators for this field
|
||||
if (! isset($validators[$path])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->formDisplayTemplate->addJsValidate($translatedPath, $validators[$path], $js);
|
||||
$this->formDisplayTemplate->addJsValidate($translatedPath, $validators[$path], $fieldValidators);
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,8 +296,8 @@ class FormDisplay
|
||||
'tabs' => $tabs,
|
||||
'forms' => $forms,
|
||||
'show_buttons' => $showButtons,
|
||||
'js_array' => $js,
|
||||
'js_default' => $jsDefault,
|
||||
'default_values' => $defaultValues,
|
||||
'field_validators' => $fieldValidators,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@ -11,9 +11,6 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
use function array_shift;
|
||||
use function json_encode;
|
||||
|
||||
use const JSON_HEX_TAG;
|
||||
|
||||
/**
|
||||
* PhpMyAdmin\Config\FormDisplayTemplate class
|
||||
@ -127,18 +124,20 @@ class FormDisplayTemplate
|
||||
/**
|
||||
* Appends JS validation code to $js_array
|
||||
*
|
||||
* @param string $fieldId ID of field to validate
|
||||
* @param string|mixed[] $validators validators callback
|
||||
* @param mixed[] $jsArray will be updated with javascript code
|
||||
* @param string $fieldId ID of field to validate
|
||||
* @param string|mixed[] $validators validators callback
|
||||
* @param mixed[] $fieldValidators will be updated with javascript code
|
||||
*/
|
||||
public function addJsValidate(string $fieldId, string|array $validators, array &$jsArray): void
|
||||
public function addJsValidate(string $fieldId, string|array $validators, array &$fieldValidators): void
|
||||
{
|
||||
foreach ((array) $validators as $validator) {
|
||||
$validator = (array) $validator;
|
||||
$vName = array_shift($validator);
|
||||
$vArgs = $validator !== [] ? ', ' . json_encode($validator, JSON_HEX_TAG) : '';
|
||||
$jsArray[] = "window.Config.registerFieldValidator('"
|
||||
. $fieldId . "', '" . $vName . "', true" . $vArgs . ')';
|
||||
$fieldValidators[] = [
|
||||
'fieldId' => $fieldId,
|
||||
'name' => $vName,
|
||||
'args' => $validator !== [] ? $validator : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -242,10 +242,8 @@ class FormDisplayTemplateTest extends AbstractTestCase
|
||||
|
||||
self::assertSame(
|
||||
[
|
||||
'window.Config.registerFieldValidator(\'testID\', \'\\\';\', true, '
|
||||
. '["\\\\r\\\\n\\\\\''
|
||||
. '\u003CscrIpt\u003E\u003C\/\' + \'script\u003E"])',
|
||||
'window.Config.registerFieldValidator(\'testID\', \'\', true)',
|
||||
['fieldId' => 'testID', 'name' => '\\\';', 'args' => ['\r\n\\\'<scrIpt></\' + \'script>']],
|
||||
['fieldId' => 'testID', 'name' => null, 'args' => null],
|
||||
],
|
||||
$js,
|
||||
);
|
||||
|
||||
@ -79,9 +79,28 @@ class PageSettingsTest extends AbstractTestCase
|
||||
self::assertStringContainsString('<input type="hidden" name="submit_save" value="Browse">', $html);
|
||||
|
||||
self::assertStringContainsString(
|
||||
"window.Config.registerFieldValidator('MaxRows', 'validatePositiveNumber', true);\n"
|
||||
. "window.Config.registerFieldValidator('RepeatCells', 'validateNonNegativeNumber', true);\n"
|
||||
. "window.Config.registerFieldValidator('LimitChars', 'validatePositiveNumber', true);\n",
|
||||
'data-field-validators="[{"fieldId":"MaxRows",'
|
||||
. '"name":"validatePositiveNumber",'
|
||||
. '"args":null},{"fieldId":"RepeatCells",'
|
||||
. '"name":"validateNonNegativeNumber",'
|
||||
. '"args":null},{"fieldId":"LimitChars",'
|
||||
. '"name":"validatePositiveNumber","args":null}]"',
|
||||
$html,
|
||||
);
|
||||
self::assertStringContainsString(
|
||||
'data-default-values="{"TableNavigationLinksMode":["icons"],'
|
||||
. '"ActionLinksMode":["both"],'
|
||||
. '"ShowAll":false,"MaxRows":[25],'
|
||||
. '"Order":["SMART"],'
|
||||
. '"BrowsePointerEnable":true,"BrowseMarkerEnable":true,'
|
||||
. '"GridEditing":["double-click"],'
|
||||
. '"SaveCellsAtOnce":false,"RepeatCells":"100",'
|
||||
. '"LimitChars":"50",'
|
||||
. '"RowActionLinks":["left"],'
|
||||
. '"RowActionLinksWithoutUnique":false,'
|
||||
. '"TablePrimaryKeyOrder":["NONE"],'
|
||||
. '"RememberSorting":true,'
|
||||
. '"RelationalDisplay":["K"]}"',
|
||||
$html,
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user