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

Added htmlParser.element.findOne #2719

Merged
merged 24 commits into from
Feb 14, 2019
Merged

Added htmlParser.element.findOne #2719

merged 24 commits into from
Feb 14, 2019

Conversation

engineering-this
Copy link
Contributor

@engineering-this engineering-this commented Jan 3, 2019

What is the purpose of this pull request?

New feature

Does your PR contain necessary tests?

All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.

This PR contains

  • Unit tests
  • Manual tests

What changes did you make?

  • Added CKEDITOR.htmlParser.element.findOne
  • Refactored Paste From Word filter function removeSymbolText.

Closes #2698.

@Comandeer Comandeer self-requested a review January 4, 2019 09:26
@Comandeer Comandeer self-assigned this Jan 4, 2019
Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

findOne method should have the same signature as find one, therefore recursive search should be activated via recursive parameter.

*
* @param {String/Function} criteria Tag name or evaluator function.
* @param {CKEDITOR.htmlParser.node} criteria.child The currently iterated child.
* @returns {CKEDITOR.htmlParser.node} First matched child, `undefined` otherwise.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If undefined is also allowed, then returned type is CKEDITOR.htmlParser.node/undefined.

Additionally IMO it should return null, as every API searching for elements returns it in case of no match.

*/
findOne: function( criteria ) {
var findMethod = typeof criteria === 'function' ? criteria : findByName,
nestedMatch,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variables without value should be declared at the end.

match = CKEDITOR.tools.array.find( this.children, function( child ) {
if ( findMethod( child ) ) {
return true;
} else if ( child.children && child.findOne ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else if statement is not necessary, as execution will end on return true; statement, if the first condition is true.

@@ -16,6 +16,14 @@ function write( el ) {
return writer.getHtml();
}

var testHtml = '<body>' +
'<p>Foo' +
'<div>Baz' +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This HTML is incorrect: div can't be nested in p tag.

@engineering-this
Copy link
Contributor Author

  • Changed returned type to null when no match is found.
  • Extracted findOne tests to separate file, so they are much better readable with html string right above TCs. Also reformatted fixture, so each node is in new line, except for elements that contain only one text.
  • Corrected changelog, and other small things.

@Comandeer Comandeer self-assigned this Jan 14, 2019
Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good, only some minor issues left.

Additionally I'm thinking about adding unit test with deeper, 2/3 level recursion – just to be sure that it really goes deeper than the first child.


return nestedMatch || match || null;

function findByName( item ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method can be inlined into ret declaration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also rename ret to something more meaningful, like match or something like that.

}
node = element.findOne( function( node ) {
return node.value && node.value.indexOf( symbol ) > -1;
}, true ),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style issue – there should be one more indentation level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding indentation level would make closing bracket higher indentation than opening, shouldn't they be the same?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a very similar case to objects in such lists and they are indented with that extra tab: https://github.com/ckeditor/ckeditor-dev/blob/1f365357c043a74e69ad21f32c829929d8610106/plugins/tableselection/plugin.js#L893-L901

( function() {
'use strict';

var testElement = CKEDITOR.htmlParser.fragment.fromHtml(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it wouldn't be more readable to move the HTML into separate file, elementfindone.html.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just some couple of style issues.

}
node = element.findOne( function( node ) {
return node.value && node.value.indexOf( symbol ) > -1;
}, true ),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a very similar case to objects in such lists and they are indented with that extra tab: https://github.com/ckeditor/ckeditor-dev/blob/1f365357c043a74e69ad21f32c829929d8610106/plugins/tableselection/plugin.js#L893-L901


element.forEach( function( node ) {
if ( node ) {
// Since symbol may contains special characters we use `indexOf` (instead of RegExp) which is sufficient (#877).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indexOf was moved up, so the comment also should.

* @param {String/Function} criteria Tag name or evaluator function.
* @param {CKEDITOR.htmlParser.node} criteria.child The currently iterated child.
* @param {Boolean} [recursive=false] If set to `true` will iterate all descendants, otherwise only direct children.
* @returns {CKEDITOR.htmlParser.node} First matched child, `null` otherwise.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be marked as nullable type.

* @returns {CKEDITOR.htmlParser.node} First matched child, `null` otherwise.
*/
findOne: function( criteria, recursive ) {
var findMethod = typeof criteria === 'function' ? criteria : function( item ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By inlining I meant "inline it directly into CKEDITOR.tools.array.find callback":

var isMatching = typeof criteria === 'function' ? criteria( child ) : item.name === criteria;

IMO such version is still readable and dedicated function findMethod is not necessary in this case.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I wanted to requested changes… Sorry for misclick.

@Comandeer Comandeer self-assigned this Jan 29, 2019
Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@engineering-this
Copy link
Contributor Author

Fixed failing test. Fail message was wrongly placed as findOne param instead of assert, as a result findOne treated message as recursive param, and assert didn't have any message to display.

Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://tests.ckeditor.test:1030/tests/core/htmlparser/elementfindone#tests%2Fcore%2Fhtmlparser%2Felementfindone%20test%20findOne%20deep%20nested%20child fails in IE8. Everything else LGTM. I've also rebased branch onto latest major and corrected API docs. I've removed criteria.child from them as it was rendered as property of criteria parameter, not a parameter passed to it.

@engineering-this
Copy link
Contributor Author

IE cuts some of text nodes. To make test constant regardless of environment I've moved tested html code back into js file and removed html file.

@Comandeer Comandeer assigned Comandeer and unassigned Comandeer Feb 14, 2019
Copy link
Member

@Comandeer Comandeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@Comandeer Comandeer merged commit 9bfa5c2 into major Feb 14, 2019
@CKEditorBot CKEditorBot deleted the t/2698 branch February 14, 2019 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants