WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
56472
Node::isContentEditable should always call parentNode() instead of parentOrHostNode()
https://bugs.webkit.org/show_bug.cgi?id=56472
Summary
Node::isContentEditable should always call parentNode() instead of parentOrHo...
Ryosuke Niwa
Reported
2011-03-16 11:14:45 PDT
Right now, Node::isContentEditable calls parentOrHostNode() when the node is not an HTML element or document. However, this is unintentional. The original patch that added HTMLElement::isContentEditable was:
http://trac.webkit.org/changeset/15643
and at this revision, parentNode() was identical to parent():
http://trac.webkit.org/browser/trunk/WebCore/dom/Node.h?rev=15643#L90
However, the behavior of parent() was changed in
http://trac.webkit.org/changeset/73618
, which resulted in unfortunate deviation of code paths. While Internet Explorer lets user edit readonly input element's content when the element is inside a contenteditable region, it's not true that we always like to make shadow DOM elements editable when the host is editable. So we should probably special-treat readonly elements instead if we want to match that behavior and not by calling parentOrHostNode() in isContentEditable(). Related change:
http://trac.webkit.org/changeset/10945
http://trac.webkit.org/changeset/15643
http://trac.webkit.org/changeset/73618
Attachments
cleanup
(2.35 KB, patch)
2011-03-16 11:36 PDT
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
use switch statement instead of ifs
(2.40 KB, patch)
2011-03-16 13:42 PDT
,
Ryosuke Niwa
darin
: review+
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Ryosuke Niwa
Comment 1
2011-03-16 11:36:00 PDT
Created
attachment 85948
[details]
cleanup
Dimitri Glazkov (Google)
Comment 2
2011-03-16 11:37:49 PDT
Comment on
attachment 85948
[details]
cleanup ok.
Darin Adler
Comment 3
2011-03-16 13:20:14 PDT
Comment on
attachment 85948
[details]
cleanup View in context:
https://bugs.webkit.org/attachment.cgi?id=85948&action=review
> Source/WebCore/dom/Node.cpp:724 > + if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) {
I’d use continue for this instead of nesting the body of the loop inside an if. Think of it as “early return” style.
Ryosuke Niwa
Comment 4
2011-03-16 13:29:18 PDT
Comment on
attachment 85948
[details]
cleanup View in context:
https://bugs.webkit.org/attachment.cgi?id=85948&action=review
>> Source/WebCore/dom/Node.cpp:724 >> + if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) { > > I’d use continue for this instead of nesting the body of the loop inside an if. Think of it as “early return” style.
I'm not sure if that's clearer. for (const Node* node = this; node; node = node->parentNode()) { if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) { if (editableLevel == RichlyEditable) return node->renderer()->style()->userModify() == READ_WRITE; EUserModify userModify = node->renderer()->style()->userModify(); return userModify == READ_WRITE || userModify == READ_WRITE_PLAINTEXT_ONLY; } } for (const Node* node = this; node; node = node->parentNode()) { if ((!node->isHTMLElement() && !node->isDocumentNode()) || !node->renderer()) continue; if (editableLevel == RichlyEditable) return node->renderer()->style()->userModify() == READ_WRITE; EUserModify userModify = node->renderer()->style()->userModify(); return userModify == READ_WRITE || userModify == READ_WRITE_PLAINTEXT_ONLY; } The latter seems confusing to me because the normal flow results in return.
Darin Adler
Comment 5
2011-03-16 13:30:40 PDT
Your call.
Ryosuke Niwa
Comment 6
2011-03-16 13:32:34 PDT
Maybe a switch statement works better here: switch (node->renderer()->style()->userModify()) { case READ_ONLY: return false; case READ_WRITE: return true; case READ_WRITE_PLAINTEXT_ONLY: return editableLevel != RichlyEditable; } ASSERT_NOT_REACHED(); return false;
Ryosuke Niwa
Comment 7
2011-03-16 13:34:25 PDT
This looks slightly better than other variants. And there's a slight performance improvement. for (const Node* node = this; node; node = node->parentNode()) { if ((node->isHTMLElement() || node->isDocumentNode()) && node->renderer()) { switch (node->renderer()->style()->userModify()) { case READ_ONLY: return false; case READ_WRITE: return true; case READ_WRITE_PLAINTEXT_ONLY: return editableLevel != RichlyEditable; } ASSERT_NOT_REACHED(); return false; } }
Darin Adler
Comment 8
2011-03-16 13:39:16 PDT
But put the return statements on separate lines. There’s no need to do it all in one line.
Ryosuke Niwa
Comment 9
2011-03-16 13:42:22 PDT
Created
attachment 85965
[details]
use switch statement instead of ifs
Darin Adler
Comment 10
2011-03-16 13:43:23 PDT
Another thought: This function can, at some point, be moved out of the Node class and into a free function in some source file int he editing directory. It doesn’t need to be a virtual function, and it doesn’t need access to anything private. So those reasons for being a member function don’t apply. The only reason I can think of is “I like the syntax”. And the function’s purpose is about editing, not the fundamental properties of DOM nodes, so there is a modularity reason to not have it be a member of the Node class.
Ryosuke Niwa
Comment 11
2011-03-16 13:46:57 PDT
(In reply to
comment #10
)
> This function can, at some point, be moved out of the Node class and into a free function in some source file int he editing directory.
>
> It doesn’t need to be a virtual function, and it doesn’t need access to anything private. So those reasons for being a member function don’t apply. The only reason I can think of is “I like the syntax”. > > And the function’s purpose is about editing, not the fundamental properties of DOM nodes, so there is a modularity reason to not have it be a member of the Node class.
Yeah. But I don't like the fact we already have so many global editing functions (e.g. ones in htmlediting.cpp) without much organizations. At some point, we need to find a way to bundle those functions together into a namespace, class, etc... because it's needlessly polluting the entire WebCore namespace as of now.
Darin Adler
Comment 12
2011-03-16 13:47:47 PDT
(In reply to
comment #11
)
> But I don't like the fact we already have so many global editing functions (e.g. ones in htmlediting.cpp) without much organizations. At some point, we need to find a way to bundle those functions together into a namespace, class, etc... because it's needlessly polluting the entire WebCore namespace as of now.
Organizing the editing functions is a good idea. But mixing editing in to the basic DOM is a far worse problem!
Ryosuke Niwa
Comment 13
2011-03-16 13:52:43 PDT
(In reply to
comment #12
)
> Organizing the editing functions is a good idea. But mixing editing in to the basic DOM is a far worse problem!
But "contenteditable" is a DOM property though (i.e. we have HTMLElement::contentEditable() and HTMLElement::setContentEditable) although I admit that Node::isContentEditable is about whether or not a node is editable and slightly different from HTMLElement::contentEditable().
Darin Adler
Comment 14
2011-03-16 13:55:09 PDT
(In reply to
comment #13
)
> But "contenteditable" is a DOM property though (i.e. we have HTMLElement::contentEditable() and HTMLElement::setContentEditable) although I admit that Node::isContentEditable is about whether or not a node is editable and slightly different from HTMLElement::contentEditable().
This is exactly my point!
Ryosuke Niwa
Comment 15
2011-03-16 14:09:10 PDT
Committed
r81277
: <
http://trac.webkit.org/changeset/81277
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug