Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dialog validators does not work if there is no 'getValue()' method provided in the current context #4473

Closed
f1ames opened this issue Jan 11, 2021 · 4 comments · Fixed by #5254
Assignees
Labels
plugin:dialog The plugin which probably causes the issue. status:confirmed An issue confirmed by the development team. type:bug A bug.
Milestone

Comments

@f1ames
Copy link
Contributor

f1ames commented Jan 11, 2021

Type of report

Bug

Provide detailed reproduction steps (if any)

The dialog plugin provides it's own set of validators, for example cssLength:

'cssLength': function( msg ) {
return this.functions( function( val ) {
return cssLengthRegex.test( CKEDITOR.tools.trim( val ) );
}, msg );
},

And the API docs states they can be simply used as follows:

CKEDITOR.dialog.validate.cssLength( 'error!' )( '10pt' );

However, such calls throws an error:

Uncaught TypeError: b.replace is not a function
    at Object.trim (ckeditor.js:30)
    at Array.<anonymous> (ckeditor.js:663)
    at ckeditor.js:663
    at <anonymous>:1:47

Expected result

It works as described in API docs.

Actual result

Error is thrown.

Other details

Well, that's the interesting part... Many of the validators use special functions() method which combines validators:

functions: function() {
var args = arguments;
return function() {
// It's important for validate functions to be able to accept the value
// as argument in addition to this.getValue(), so that it is possible to
// combine validate functions together to make more sophisticated
// validators.
var value = this && this.getValue ? this.getValue() : args[ 0 ];
var msg,
relation = CKEDITOR.VALIDATE_AND,
functions = [],
i;
for ( i = 0; i < args.length; i++ ) {
if ( typeof args[ i ] == 'function' )
functions.push( args[ i ] );
else
break;
}
if ( i < args.length && typeof args[ i ] == 'string' ) {
msg = args[ i ];
i++;
}
if ( i < args.length && typeof args[ i ] == 'number' )
relation = args[ i ];
var passed = ( relation == CKEDITOR.VALIDATE_AND ? true : false );
for ( i = 0; i < functions.length; i++ ) {
if ( relation == CKEDITOR.VALIDATE_AND )
passed = passed && functions[ i ]( value );
else
passed = passed || functions[ i ]( value );
}
return !passed ? msg : true;
};
},

When the validator is created (like in cssLength above), functions() returns another function (let's call it validatorFn()) which has access to initial args. This means calling CKEDITOR.dialog.validate.cssLength( 'error!' ) internally calls:

.functions( `cssLengthInternalFn`, `error!` )

return this.functions( function( val ) {
return cssLengthRegex.test( CKEDITOR.tools.trim( val ) );
}, msg );

Which returns validatorFn() mentioned above. This functions accesses the value to be validated in two ways. Using getValue() method from the current context or accessing args[ 0 ] (the ones from functions() call):

var value = this && this.getValue ? this.getValue() : args[ 0 ];

If getValue() method is present in the current context everything works fine. But if not, args[ 0 ] are used as a value to be validated. However, in the context of .functions( cssLengthInternalFn, 'error!' ) call, args[ 0 ] are cssLengthInternalFn (so the validator function). And so args[ 0 ] are both used as validator function and value to be validated (not a string so Uncaught TypeError: b.replace is not a function is thrown).

I wonder if the API docs are just confusing and it was never meant to be used without extending dialog and adding getValue() there, but the comment there states it should work:

// It's important for validate functions to be able to accept the value
// as argument in addition to this.getValue(), so that it is possible to
// combine validate functions together to make more sophisticated
// validators.
var value = this && this.getValue ? this.getValue() : args[ 0 ];

  • Browser: All
  • OS: All
  • CKEditor version: At least 4.10.0 but looking at git history it might be 4.0.0 as well 🤔
  • Installed CKEditor plugins: dialog
@f1ames f1ames added type:bug A bug. status:confirmed An issue confirmed by the development team. plugin:dialog The plugin which probably causes the issue. labels Jan 11, 2021
@f1ames f1ames changed the title Dialog validators doesn't work if there is no 'getValue()' method provided in the current context Dialog validators does nott work if there is no 'getValue()' method provided in the current context Jan 11, 2021
@bunglegrind
Copy link
Contributor

Related? #4449

@f1ames
Copy link
Contributor Author

f1ames commented Jan 12, 2021

Related? #4449

@bunglegrind I was checking it, but it seems those are different issues. As you mentioned in #4449 (comment)

Or explicity check for boolean (=== true) in the following lines...

Should be enough to fix #4449. And here the fix would be replacing:

var value = this && this.getValue ? this.getValue() : args[ 0 ];

with

var value = this && this.getValue ? this.getValue() : arguments[ 0 ];

so that arguments from validatorFn() are used instead of the one bond to functions() context call.

Still, it would be reasonable to fix both in one PR seems they concern the same function.

@sculpt0r
Copy link
Contributor

sculpt0r commented Feb 9, 2022

Looks like notEmpty validator contains also part of the fix logic - so we definitely could solve this for all validators.

@jacekbogdanski jacekbogdanski changed the title Dialog validators does nott work if there is no 'getValue()' method provided in the current context Dialog validators does not work if there is no 'getValue()' method provided in the current context Feb 16, 2022
@sculpt0r sculpt0r self-assigned this Jul 2, 2022
sculpt0r added a commit that referenced this issue Jul 5, 2022
- establish validators results based on doc samples
sculpt0r added a commit that referenced this issue Jul 5, 2022
get rid of extra code caused by #4473
jacekbogdanski pushed a commit that referenced this issue Jul 6, 2022
- establish validators results based on doc samples
jacekbogdanski pushed a commit that referenced this issue Jul 6, 2022
get rid of extra code caused by #4473
@CKEditorBot
Copy link
Collaborator

Closed in #5254

@CKEditorBot CKEditorBot added this to the 4.19.1 milestone Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
plugin:dialog The plugin which probably causes the issue. status:confirmed An issue confirmed by the development team. type:bug A bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants