OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND | |
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE | |
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
23 * SUCH DAMAGE. | |
24 */ | |
25 | |
26 #include "web/ValidationMessageClientImpl.h" | |
27 | |
28 #include "core/dom/Element.h" | |
29 #include "core/dom/TaskRunnerHelper.h" | |
30 #include "core/exported/WebViewBase.h" | |
31 #include "core/frame/FrameView.h" | |
32 #include "core/page/ChromeClient.h" | |
33 #include "platform/PlatformChromeClient.h" | |
34 #include "platform/wtf/CurrentTime.h" | |
35 #include "public/platform/WebRect.h" | |
36 #include "public/platform/WebString.h" | |
37 #include "public/web/WebTextDirection.h" | |
38 #include "public/web/WebViewClient.h" | |
39 | |
40 namespace blink { | |
41 | |
42 ValidationMessageClientImpl::ValidationMessageClientImpl(WebViewBase& web_view) | |
43 : web_view_(web_view), | |
44 current_anchor_(nullptr), | |
45 last_page_scale_factor_(1), | |
46 finish_time_(0) {} | |
47 | |
48 ValidationMessageClientImpl* ValidationMessageClientImpl::Create( | |
49 WebViewBase& web_view) { | |
50 return new ValidationMessageClientImpl(web_view); | |
51 } | |
52 | |
53 ValidationMessageClientImpl::~ValidationMessageClientImpl() {} | |
54 | |
55 FrameView* ValidationMessageClientImpl::CurrentView() { | |
56 return current_anchor_->GetDocument().View(); | |
57 } | |
58 | |
59 void ValidationMessageClientImpl::ShowValidationMessage( | |
60 const Element& anchor, | |
61 const String& message, | |
62 TextDirection message_dir, | |
63 const String& sub_message, | |
64 TextDirection sub_message_dir) { | |
65 if (message.IsEmpty()) { | |
66 HideValidationMessage(anchor); | |
67 return; | |
68 } | |
69 if (!anchor.GetLayoutBox()) | |
70 return; | |
71 if (current_anchor_) | |
72 HideValidationMessage(*current_anchor_); | |
73 current_anchor_ = &anchor; | |
74 IntRect anchor_in_viewport = | |
75 CurrentView()->ContentsToViewport(anchor.PixelSnappedBoundingBox()); | |
76 last_anchor_rect_in_screen_ = | |
77 CurrentView()->GetChromeClient()->ViewportToScreen(anchor_in_viewport, | |
78 CurrentView()); | |
79 last_page_scale_factor_ = web_view_.PageScaleFactor(); | |
80 message_ = message; | |
81 const double kMinimumSecondToShowValidationMessage = 5.0; | |
82 const double kSecondPerCharacter = 0.05; | |
83 const double kStatusCheckInterval = 0.1; | |
84 | |
85 web_view_.Client()->ShowValidationMessage( | |
86 anchor_in_viewport, message_, ToWebTextDirection(message_dir), | |
87 sub_message, ToWebTextDirection(sub_message_dir)); | |
88 web_view_.ChromeClient().RegisterPopupOpeningObserver(this); | |
89 | |
90 finish_time_ = | |
91 MonotonicallyIncreasingTime() + | |
92 std::max(kMinimumSecondToShowValidationMessage, | |
93 (message.length() + sub_message.length()) * kSecondPerCharacter); | |
94 // FIXME: We should invoke checkAnchorStatus actively when layout, scroll, | |
95 // or page scale change happen. | |
96 timer_ = WTF::MakeUnique<TaskRunnerTimer<ValidationMessageClientImpl>>( | |
97 TaskRunnerHelper::Get(TaskType::kUnspecedTimer, &anchor.GetDocument()), | |
98 this, &ValidationMessageClientImpl::CheckAnchorStatus); | |
99 timer_->StartRepeating(kStatusCheckInterval, BLINK_FROM_HERE); | |
100 } | |
101 | |
102 void ValidationMessageClientImpl::HideValidationMessage(const Element& anchor) { | |
103 if (!current_anchor_ || !IsValidationMessageVisible(anchor)) | |
104 return; | |
105 timer_ = nullptr; | |
106 current_anchor_ = nullptr; | |
107 message_ = String(); | |
108 finish_time_ = 0; | |
109 web_view_.Client()->HideValidationMessage(); | |
110 web_view_.ChromeClient().UnregisterPopupOpeningObserver(this); | |
111 } | |
112 | |
113 bool ValidationMessageClientImpl::IsValidationMessageVisible( | |
114 const Element& anchor) { | |
115 return current_anchor_ == &anchor; | |
116 } | |
117 | |
118 void ValidationMessageClientImpl::WillUnloadDocument(const Document& document) { | |
119 if (current_anchor_ && current_anchor_->GetDocument() == document) | |
120 HideValidationMessage(*current_anchor_); | |
121 } | |
122 | |
123 void ValidationMessageClientImpl::DocumentDetached(const Document& document) { | |
124 DCHECK(!current_anchor_ || current_anchor_->GetDocument() != document) | |
125 << "willUnloadDocument() should be called beforehand."; | |
126 } | |
127 | |
128 void ValidationMessageClientImpl::CheckAnchorStatus(TimerBase*) { | |
129 DCHECK(current_anchor_); | |
130 if (MonotonicallyIncreasingTime() >= finish_time_ || !CurrentView()) { | |
131 HideValidationMessage(*current_anchor_); | |
132 return; | |
133 } | |
134 | |
135 IntRect new_anchor_rect_in_viewport = | |
136 current_anchor_->VisibleBoundsInVisualViewport(); | |
137 if (new_anchor_rect_in_viewport.IsEmpty()) { | |
138 HideValidationMessage(*current_anchor_); | |
139 return; | |
140 } | |
141 | |
142 IntRect new_anchor_rect_in_viewport_in_screen = | |
143 CurrentView()->GetChromeClient()->ViewportToScreen( | |
144 new_anchor_rect_in_viewport, CurrentView()); | |
145 if (new_anchor_rect_in_viewport_in_screen == last_anchor_rect_in_screen_ && | |
146 web_view_.PageScaleFactor() == last_page_scale_factor_) | |
147 return; | |
148 last_anchor_rect_in_screen_ = new_anchor_rect_in_viewport_in_screen; | |
149 last_page_scale_factor_ = web_view_.PageScaleFactor(); | |
150 web_view_.Client()->MoveValidationMessage(new_anchor_rect_in_viewport); | |
151 } | |
152 | |
153 void ValidationMessageClientImpl::WillBeDestroyed() { | |
154 if (current_anchor_) | |
155 HideValidationMessage(*current_anchor_); | |
156 } | |
157 | |
158 void ValidationMessageClientImpl::WillOpenPopup() { | |
159 if (current_anchor_) | |
160 HideValidationMessage(*current_anchor_); | |
161 } | |
162 | |
163 DEFINE_TRACE(ValidationMessageClientImpl) { | |
164 visitor->Trace(current_anchor_); | |
165 ValidationMessageClient::Trace(visitor); | |
166 } | |
167 | |
168 } // namespace blink | |
OLD | NEW |