Opened 10 years ago
Closed 10 years ago
#12279 closed New Feature (fixed)
Allow passing custom evaluator to node.getAscendant
Reported by: | AlexW | Owned by: | Artur Delura |
---|---|---|---|
Priority: | Normal | Milestone: | CKEditor 4.4.5 |
Component: | General | Version: | |
Keywords: | Cc: |
Description
getAscendant is a bit limited, would be handy if it could filter by classes too.
// <div class="outer"><div class="inner"><p><b>Some text</b></p></div></div> // If node == <b> ascendant = node.getAscendant('div.outer'); // ascendant == <div class="outer">
Change History (14)
comment:1 Changed 10 years ago by
Status: | new → confirmed |
---|
comment:2 Changed 10 years ago by
Owner: | set to Artur Delura |
---|---|
Status: | confirmed → assigned |
comment:3 Changed 10 years ago by
Do we want indroduce function as a second/third argument (second one is optional) or allow place function as a first argument instead of string (node name)? I preffer second option because it's more flexible - we are not forced to specify node name. Both options of course with backward compability.
comment:5 Changed 10 years ago by
Status: | assigned → review |
---|
Solution and tests in branch:t/12279. See documentation as well. We could also implement http://en.wikipedia.org/wiki/Visitor_pattern in the future.
comment:6 Changed 10 years ago by
We could also implement http://en.wikipedia.org/wiki/Visitor_pattern in the future.
I don't think it's possible or necessary:
The visitor pattern requires a programming language that supports single dispatch and method overloading
comment:7 Changed 10 years ago by
I already implemented this pattern in JavaScript, maybe because I didn't know that such stuff is required ;). Function as a first class object is enought i think. It could bring us a lot of flexibility and less code.
comment:8 follow-up: 9 Changed 10 years ago by
Status: | review → review_failed |
---|
Well, it's a variation about visitor pattern (because in your callback you have to handle type discovery - in visitor pattern it should happen automatically). But that's just naming - not important here, since callback is a standard (and much simpler) solution in JS world.
I found few issues after first glance:
- Callback should be executed with
CKEDITOR.dom.element
instance. But avoid creating instances when filtering by name (performance). - Run linter.
- You can compare CKEDITOR.dom.nodes using assert.areSame without accessing
$
property. - You should split test cases into separate function and name them properly. It's hard to guess what you're testing. Don't use assertion message for that.
- 'func_check' is not the right id. Neither name itself, nor its format. Use something that will tell that it's for getAscendant test - the same as other tests do.
- We use
el
rather thanelem
.
comment:9 Changed 10 years ago by
Status: | review_failed → review |
---|
- Run linter.
Found unused variable.
- 'func_check' is not the right id. Neither name itself, nor its format. Use something that will tell that it's for getAscendant test - the same as other tests do.
As always I write tests in same style as closest environment is written.
Changes in the same branch.
comment:10 follow-up: 11 Changed 10 years ago by
Status: | review → review_failed |
---|
As always I write tests in same style as closest environment is written.
Well, from the same file:
<div id="insertAfter"><!--abc-->def</div> <div id="insertBefore"><!--abc-->def</div> <div><br><br><!--a--><br><div>text<!--b-->text<p>text<br><i id="getAddress1">text</i></p></div></div> <div><span><span><span><span><i id="getAddress2"></i></span></span></span></span></div> <iframe id="getDocument"></iframe> <div id="getNSN"> <i id="getNSN1">1</i> <i id="getNSN2">2</i> <i id="getNSN3">3</i>
So func_check
definitely does not fit here. All ids are camel cased and are references to tested methods names.
var el = ( conditionChecker === reference ? new CKEDITOR.dom.node( $ ) : $ );
This may be optimized. You can avoid two things:
- Unnecessary assignment if callback was passed - don't create unnecessary
el
variable in this case. - Checking whether callback was passed in every loop step.
comment:11 Changed 10 years ago by
var el = ( conditionChecker === reference ? new CKEDITOR.dom.node( $ ) : $ );This may be optimized. You can avoid two things:
- Unnecessary assignment if callback was passed - don't create unnecessary
el
variable in this case.
I make such variables to avoid very long lines, which make code hard to read. When I will join this two lines into one it will have over 100 characters length. Common standard is less than 80. Maybe you don't see problem but I do, because in my IDE I have font size set to 18.
- Checking whether callback was passed in every loop step.
So you want to move that check out of while loop? Just like:
var customChecker = conditionChecker === reference; while() {
If yes, it does not make sense. We shouldn't optimize everything, but just parts which are slow. I made a quick performance tests and found out that such checking need to be called 23585 times to take 1ms. It's nothing.
comment:12 follow-up: 13 Changed 10 years ago by
First of all - do not create microbenchmarks. Never do that. You just tested empty loop or no loop at all.
Second - the reason for this changes is sanity - it simply does not make sense to test the value every time or make variable assignments when they are totally unnecessary there.
Also, think about readability - if you make a variable check every time, does this mean that this variable may change during the iteration? Code which does not do unnecessary things will be more clear for the reader.
Finally, note that I didn't mention performance in comment:9 ;).
comment:13 Changed 10 years ago by
Status: | review_failed → review |
---|
Second - the reason for this changes is sanity - it simply does not make sense to test the value every time or make variable assignments when they are totally unnecessary there.
Also, think about readability - if you make a variable check every time, does this mean that this variable may change during the iteration? Code which does not do unnecessary things will be more clear for the reader.
Finally, note that I didn't mention performance in comment:9 ;).
That make sense, thought you want this improvements because of performance. +1 for readability :) Changes in same branch:t/12279.
comment:14 Changed 10 years ago by
Milestone: | → CKEditor 4.4.5 |
---|---|
Resolution: | → fixed |
Status: | review → closed |
Summary: | Allow class selection in getAscendant → Allow passing custom evaluator to node.getAscendant |
There were still some issues which I mentioned earlier and which hasn't been resolved, so I pushed additional commit.
Merged to master with git:8749148.
I was also surprised that this function can do so little - I needed to look for an attribute and had to write it manually. So I'm also for extending it, though it must be a callback, not a CSS selector, because this will be faster and simpler to code (shorter too).