blob: 11e5ab0325334257cc915b7b6ab6549d4183849b [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
#include <memory>
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/position.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
namespace blink {
class TextControlElementTest : public testing::Test {
protected:
void SetUp() override;
DummyPageHolder& Page() const { return *dummy_page_holder_; }
Document& GetDocument() const { return *document_; }
TextControlElement& TextControl() const { return *text_control_; }
HTMLInputElement& Input() const { return *input_; }
void UpdateAllLifecyclePhases() {
GetDocument().View()->UpdateAllLifecyclePhasesForTest();
}
private:
std::unique_ptr<DummyPageHolder> dummy_page_holder_;
Persistent<Document> document_;
Persistent<TextControlElement> text_control_;
Persistent<HTMLInputElement> input_;
};
void TextControlElementTest::SetUp() {
Page::PageClients page_clients;
FillWithEmptyClients(page_clients);
dummy_page_holder_ =
std::make_unique<DummyPageHolder>(IntSize(800, 600), &page_clients);
document_ = &dummy_page_holder_->GetDocument();
document_->documentElement()->setInnerHTML(
"<body><textarea id=textarea></textarea><input id=input /></body>");
UpdateAllLifecyclePhases();
text_control_ = ToTextControl(document_->getElementById("textarea"));
text_control_->focus();
input_ = To<HTMLInputElement>(document_->getElementById("input"));
}
TEST_F(TextControlElementTest, SetSelectionRange) {
EXPECT_EQ(0u, TextControl().selectionStart());
EXPECT_EQ(0u, TextControl().selectionEnd());
TextControl().SetInnerEditorValue("Hello, text form.");
EXPECT_EQ(0u, TextControl().selectionStart());
EXPECT_EQ(0u, TextControl().selectionEnd());
TextControl().SetSelectionRange(1, 3);
EXPECT_EQ(1u, TextControl().selectionStart());
EXPECT_EQ(3u, TextControl().selectionEnd());
}
TEST_F(TextControlElementTest, SetSelectionRangeDoesNotCauseLayout) {
Input().focus();
Input().setValue("Hello, input form.");
Input().SetSelectionRange(1, 1);
// Force layout if document().updateStyleAndLayoutIgnorePendingStylesheets()
// is called.
GetDocument().body()->AppendChild(GetDocument().createTextNode("foo"));
unsigned start_layout_count = Page().GetFrameView().LayoutCountForTesting();
EXPECT_TRUE(GetDocument().NeedsLayoutTreeUpdate());
Input().SetSelectionRange(2, 2);
EXPECT_EQ(start_layout_count, Page().GetFrameView().LayoutCountForTesting());
}
TEST_F(TextControlElementTest, IndexForPosition) {
Input().setValue("Hello");
HTMLElement* inner_editor = Input().InnerEditorElement();
EXPECT_EQ(5u, TextControlElement::IndexForPosition(
inner_editor,
Position(inner_editor, PositionAnchorType::kAfterAnchor)));
}
TEST_F(TextControlElementTest, ReadOnlyAttributeChangeEditability) {
Input().setAttribute(html_names::kStyleAttr, "all:initial");
Input().setAttribute(html_names::kReadonlyAttr, "");
UpdateAllLifecyclePhases();
EXPECT_EQ(EUserModify::kReadOnly,
Input().InnerEditorElement()->GetComputedStyle()->UserModify());
Input().removeAttribute(html_names::kReadonlyAttr);
UpdateAllLifecyclePhases();
EXPECT_EQ(EUserModify::kReadWritePlaintextOnly,
Input().InnerEditorElement()->GetComputedStyle()->UserModify());
}
TEST_F(TextControlElementTest, DisabledAttributeChangeEditability) {
Input().setAttribute(html_names::kStyleAttr, "all:initial");
Input().setAttribute(html_names::kDisabledAttr, "");
UpdateAllLifecyclePhases();
EXPECT_EQ(EUserModify::kReadOnly,
Input().InnerEditorElement()->GetComputedStyle()->UserModify());
Input().removeAttribute(html_names::kDisabledAttr);
UpdateAllLifecyclePhases();
EXPECT_EQ(EUserModify::kReadWritePlaintextOnly,
Input().InnerEditorElement()->GetComputedStyle()->UserModify());
}
} // namespace blink