summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
blob: e5f900301bcb033386b3123264fc270ae74bdd1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 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()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
  }

 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