isContentEditable shouldn't trigger synchronous style recalc in most cases
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Mar 2015 19:52:21 +0000 (19:52 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 1 Mar 2015 19:52:21 +0000 (19:52 +0000)
commit56be91bcfe085b28f96a7050856db88a701cd020
treef9dd47c6e778589114b7647113ee8a6820be584d
parent4b1300f7b61f8368c82e7de4c1a2f6cbd8cc8d8f
isContentEditable shouldn't trigger synchronous style recalc in most cases
https://bugs.webkit.org/show_bug.cgi?id=129034

Reviewed by Antti Koivisto.

Source/WebCore:

Avoid style recalc inside isContentEditable when the document doesn't contain -webkit-user-modify or
-webkit-user-select: all. Instead, compute the value from contenteditable attributes in ancestors.
However, still compute the editability from the style tree when it's up-to-date in order to avoid
repeatedly walking up the DOM tree in a hot code path inside editing.

Test: fast/dom/HTMLElement/dynamic-editability-change.html

* css/CSSGrammar.y.in: No need to pass in "true" as we never call this function with false.
* css/CSSParser.cpp:
(WebCore::isValidKeywordPropertyAndValue): Calls parserSetUsesStyleBasedEditability as needed.
(WebCore::parseKeywordValue): Passes around StyleSheetContents*.
(WebCore::CSSParser::parseValue): Ditto.
(WebCore::CSSParser::parseFont): Ditto.

* css/StyleSheetContents.cpp:
(WebCore::StyleSheetContents::StyleSheetContents): Initializes and copies m_usesStyleBasedEditability.

* css/StyleSheetContents.h:
(WebCore::StyleSheetContents::parserSetUsesRemUnits): Removed the argument since it was always true.
(WebCore::StyleSheetContents::parserSetUsesStyleBasedEditability): Added.
(WebCore::StyleSheetContents::usesStyleBasedEditability): Added.

* dom/Document.cpp:
(WebCore::Document::recalcStyle): Added a FIXME as well as a comment explaining why we don't call
setUsesStyleBasedEditability. Since Node::computeEditability triggers style recalc only when the flag
is set to true, it's too late to update the flag here.
(WebCore::Document::updateStyleIfNeeded): Uses a newly extracted needsStyleRecalc.
(WebCore::Document::updateBaseURL): Preserves m_usesStyleBasedEditability as well as m_usesRemUnit.
(WebCore::Document::usesStyleBasedEditability): Added. Returns true when inline style declarations or
any active stylesheet uses -webkit-user-modify or -webkit-user-select: all. Flushing pending stylesheet
changes here is fine because the alternative is to trigger a full blown style recalc.

* dom/Document.h:
(WebCore::Document::needsStyleRecalc): Added. Extracted from updateStyleIfNeeded.

* dom/DocumentStyleSheetCollection.cpp:
(WebCore::DocumentStyleSheetCollection::DocumentStyleSheetCollection):
(WebCore::styleSheetsUseRemUnits): Deleted.
(WebCore::DocumentStyleSheetCollection::updateActiveStyleSheets): Updates m_usesStyleBasedEditability
as well as m_usesRemUnit.

* dom/DocumentStyleSheetCollection.h:
(WebCore::DocumentStyleSheetCollection::usesStyleBasedEditability): Added.
(WebCore::DocumentStyleSheetCollection::setUsesStyleBasedEditability): Added.

* dom/Node.cpp:
(WebCore::computeEditabilityFromComputedStyle): Extracted from computeEditability.
(WebCore::Node::computeEditability): When the style recalc is requested and the render tree is dirty,
check if the document uses any CSS property that can affect the editability of elements. If it doesn't,
compute the editability from contenteditable attributes in the anchors via matchesReadWritePseudoClass.
Continue to use the style-based computation when the render tree isn't dirty to avoid the tree walk.

* html/HTMLElement.cpp:
(WebCore::HTMLElement::editabilityFromContentEditableAttr): Extracted from matchesReadWritePseudoClass
to be called in Node::computeEditability. Also made it return Editability instead of boolean.
(WebCore::HTMLElement::matchesReadWritePseudoClass):
* html/HTMLElement.h:

LayoutTests:

Added a regression test to update the editability of elements dynamically. Also rebaselined
tests per style recalc timing changes.

* fast/dom/HTMLElement/dynamic-editability-change-expected.txt: Added.
* fast/dom/HTMLElement/dynamic-editability-change.html: Added.
* platform/mac/editing/execCommand/5142012-1-expected.txt: anonymous render block differences.
* platform/mac/editing/execCommand/nsresponder-outdent-expected.txt: Ditto.
* platform/mac/editing/inserting/insert-at-end-02-expected.txt: Empty render text differences.
* platform/mac/editing/pasteboard/4989774-expected.txt: Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180867 268f45cc-cd09-0410-ab3c-d52691b4dbfc
19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLElement/dynamic-editability-change-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLElement/dynamic-editability-change.html [new file with mode: 0644]
LayoutTests/platform/mac/editing/execCommand/5142012-1-expected.txt
LayoutTests/platform/mac/editing/execCommand/nsresponder-outdent-expected.txt
LayoutTests/platform/mac/editing/inserting/insert-at-end-02-expected.txt
LayoutTests/platform/mac/editing/pasteboard/4989774-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/css/CSSGrammar.y.in
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/StyleSheetContents.cpp
Source/WebCore/css/StyleSheetContents.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/DocumentStyleSheetCollection.cpp
Source/WebCore/dom/DocumentStyleSheetCollection.h
Source/WebCore/dom/Node.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLElement.h