diff options
author | pdr@chromium.org <pdr@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2014-05-21 01:45:33 +0000 |
---|---|---|
committer | pdr@chromium.org <pdr@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2014-05-21 01:45:33 +0000 |
commit | 4fe4a2b760323ff96dd23a98c1bbfcfa0e20d631 (patch) | |
tree | 37c8397fbd8f13e3b04f302caa1e3e6b383f2ec6 | |
parent | 7597477bc6493b744ccb7c5d9b488c805dabc52b (diff) | |
download | chromium_src-4fe4a2b760323ff96dd23a98c1bbfcfa0e20d631.zip chromium_src-4fe4a2b760323ff96dd23a98c1bbfcfa0e20d631.tar.gz chromium_src-4fe4a2b760323ff96dd23a98c1bbfcfa0e20d631.tar.bz2 |
[FastTextAutosizer] Rework form input handling
This patch reworks how we handle form input by removing the hash
lookup of specific element types in favor of checking
isFormControlElement. This is faster and includes the fieldset
element which is considered a form control, fixing a bug on
http://forum.nationstates.net.
Detailed description of changes:
1) Switch isFormInput's argument from const Element* to
const RenderObject* which lets us move the duplicated
node logic from the callers into isFormInput. One of the
callers used node() and the other used generatingNode()
so this may have fixed a subtle bug as well.
2) Change isFormInput to check isFormControlElement
instead of checking the tagname.
3) Add a special-case for HTMLTextAreaElement which
should be autosized unlike the other form control
elements. See various special-cases sprinkled in
FastTextAutosizer.cpp
4) Rename isFormInput to isNonTextAreaFormControl.
5) Refactor blockContainsFormInput as
blockOrImmediateChildrenAreFormControls and cleanup
the code.
BUG=373539
Review URL: https://codereview.chromium.org/295913002
git-svn-id: svn://svn.chromium.org/blink/trunk@174437 bbb929c8-8fbe-4397-9dbb-9b2b20218538
3 files changed, 129 insertions, 20 deletions
diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element-expected.html b/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element-expected.html new file mode 100644 index 0000000..a516612 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element-expected.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html style="font-size: 16px"> +<head> + +<meta name="viewport" content="width=800"> +<style> + body { + width: 800px; + margin: 0; + overflow-y: hidden; + } + fieldset { + margin-top: 0.5em; + } +</style> + +</head> +<body> + +<div style="font-size: 2.5rem"> + This paragraph should be autosized to 40px computed font-size (16 * 800/320), + whereas the input text fields should be rendered at their default font size and + the accompanying text below should remain 16px. +</div> + +<div> + <fieldset> + <legend>Not autosized title</legend> + <input type="email" name="email" id="email" value="noautosize@aol.com"> <label for="email">Not autosized email</label> + <br> + <input type="radio" name="radio" id="radio"> <label for="radio">Not autosized radio</label> + </fieldset> +</div> +<div> + <fieldset> + <input type="text" name="text" id="text" value="not autosized text"> + </fieldset> +</div> +<div> + <fieldset> + <legend>Not autosized title</legend> + This text should not be autosized. + </fieldset> +</div> +<div> + <fieldset> + <textarea>This text should not be autosized.</textarea> + </fieldset> +</div> +<div style="font-size: 2.5rem"> + This text should be autosized. +</div> + +</body> +</html> diff --git a/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element.html b/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element.html new file mode 100644 index 0000000..fe224aa --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text-autosizing/form-controls-autosizing-fieldset-element.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html style="font-size: 16px"> +<head> + +<meta name="viewport" content="width=800"> +<style> + body { + width: 800px; + margin: 0; + overflow-y: hidden; + } + fieldset { + margin-top: 0.5em; + } +</style> + +<script src="resources/autosizingTest.js"></script> + +</head> +<body> + +<div> + This paragraph should be autosized to 40px computed font-size (16 * 800/320), + whereas the input text fields should be rendered at their default font size and + the accompanying text below should remain 16px. +</div> + +<div> + <fieldset> + <legend>Not autosized title</legend> + <input type="email" name="email" id="email" value="noautosize@aol.com"> <label for="email">Not autosized email</label> + <br> + <input type="radio" name="radio" id="radio"> <label for="radio">Not autosized radio</label> + </fieldset> +</div> +<div> + <fieldset> + <input type="text" name="text" id="text" value="not autosized text"> + </fieldset> +</div> +<div> + <fieldset> + <legend>Not autosized title</legend> + This text should not be autosized. + </fieldset> +</div> +<div> + <fieldset> + <textarea>This text should not be autosized.</textarea> + </fieldset> +</div> +<div> + This text should be autosized. +</div> + +</body> +</html> diff --git a/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp b/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp index 7db03c3..1145aaa 100644 --- a/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp +++ b/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp @@ -35,6 +35,7 @@ #include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" +#include "core/html/HTMLTextAreaElement.h" #include "core/page/Page.h" #include "core/rendering/InlineIterator.h" #include "core/rendering/RenderBlock.h" @@ -129,15 +130,14 @@ static const RenderObject* parentElementRenderer(const RenderObject* renderer) return 0; } -static bool isFormInput(const Element* element) +static bool isNonTextAreaFormControl(const RenderObject* renderer) { - DEFINE_STATIC_LOCAL(Vector<QualifiedName>, formInputTags, ()); - if (formInputTags.isEmpty()) { - formInputTags.append(HTMLNames::inputTag); - formInputTags.append(HTMLNames::buttonTag); - formInputTags.append(HTMLNames::selectTag); - } - return formInputTags.contains(element->tagQName()); + const Node* node = renderer ? renderer->node() : 0; + if (!node || !node->isElementNode()) + return false; + const Element* element = toElement(node); + + return (element->isFormControlElement() && !isHTMLTextAreaElement(element)); } static bool isPotentialClusterRoot(const RenderObject* renderer) @@ -158,9 +158,8 @@ static bool isPotentialClusterRoot(const RenderObject* renderer) return false; if (renderer->isListItem()) return (renderer->isFloating() || renderer->isOutOfFlowPositioned()); - // Avoid creating containers for text within text controls, buttons, or <select> buttons. - Node* parentNode = renderer->parent() ? renderer->parent()->generatingNode() : 0; - if (parentNode && parentNode->isElementNode() && isFormInput(toElement(parentNode))) + // Avoid creating containers for text within form input. + if (isNonTextAreaFormControl(renderer->parent())) return false; return true; @@ -241,17 +240,15 @@ static bool blockHeightConstrained(const RenderBlock* block) return false; } -static bool blockContainsFormInput(const RenderBlock* block) +static bool blockOrImmediateChildrenAreFormControls(const RenderBlock* block) { - const RenderObject* renderer = block; + if (isNonTextAreaFormControl(block)) + return true; + const RenderObject* renderer = block->slowFirstChild(); while (renderer) { - const Node* node = renderer->node(); - if (node && node->isElementNode() && isFormInput(toElement(node))) + if (isNonTextAreaFormControl(renderer)) return true; - if (renderer == block) - renderer = renderer->nextInPreOrder(block); - else - renderer = renderer->nextInPreOrderAfterChildren(block); + renderer = renderer->nextSibling(); } return false; @@ -260,7 +257,7 @@ static bool blockContainsFormInput(const RenderBlock* block) // Some blocks are not autosized even if their parent cluster wants them to. static bool blockSuppressesAutosizing(const RenderBlock* block) { - if (blockContainsFormInput(block)) + if (blockOrImmediateChildrenAreFormControls(block)) return true; if (blockIsRowOfLinks(block)) |