Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: Source/web/WebFrameWidgetImpl.cpp

Issue 638003004: Introduce WebFrameWidget to Blink (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: More review updates Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2014 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "web/WebFrameWidgetImpl.h"
33
34 #include "core/editing/Editor.h"
35 #include "core/editing/FrameSelection.h"
36 #include "core/editing/InputMethodController.h"
37 #include "core/editing/PlainTextRange.h"
38 #include "core/frame/FrameHost.h"
39 #include "core/frame/FrameView.h"
40 #include "core/frame/RemoteFrame.h"
41 #include "core/frame/Settings.h"
42 #include "core/page/EventHandler.h"
43 #include "core/page/FocusController.h"
44 #include "core/page/Page.h"
45 #include "core/rendering/HitTestResult.h"
46 #include "core/rendering/RenderView.h"
47 #include "core/rendering/compositing/RenderLayerCompositor.h"
48 #include "platform/KeyboardCodes.h"
49 #include "platform/NotImplemented.h"
50 #include "platform/TraceEvent.h"
51 #include "public/web/WebAXObject.h"
52 #include "public/web/WebActiveWheelFlingParameters.h"
53 #include "public/web/WebAutofillClient.h"
54 #include "public/web/WebBeginFrameArgs.h"
55 #include "public/web/WebFrameClient.h"
56 #include "public/web/WebHitTestResult.h"
57 #include "public/web/WebInputElement.h"
58 #include "public/web/WebMediaPlayerAction.h"
59 #include "public/web/WebNode.h"
60 #include "public/web/WebPlugin.h"
61 #include "public/web/WebPluginAction.h"
62 #include "public/web/WebRange.h"
63 #include "public/web/WebTextInputInfo.h"
64 #include "public/web/WebViewClient.h"
65 #include "public/web/WebWindowFeatures.h"
66 #include "web/CompositionUnderlineVectorBuilder.h"
67 #include "web/ContextFeaturesClientImpl.h"
68 #include "web/DatabaseClientImpl.h"
69 #include "web/FullscreenController.h"
70 #include "web/GraphicsLayerFactoryChromium.h"
71 #include "web/LinkHighlight.h"
72 #include "web/NavigatorContentUtilsClientImpl.h"
73 #include "web/PrerendererClientImpl.h"
74 #include "web/SpeechRecognitionClientProxy.h"
75 #include "web/StorageQuotaClientImpl.h"
76 #include "web/ValidationMessageClientImpl.h"
77 #include "web/ViewportAnchor.h"
78 #include "web/WebDevToolsAgentImpl.h"
79 #include "web/WebDevToolsAgentPrivate.h"
80 #include "web/WebInputEventConversion.h"
81 #include "web/WebLocalFrameImpl.h"
82 #include "web/WebPluginContainerImpl.h"
83 #include "web/WebRemoteFrameImpl.h"
84 #include "web/WebSettingsImpl.h"
85 #include "web/WebViewImpl.h"
86 #include "web/WorkerGlobalScopeProxyProviderImpl.h"
87 #include "web/painting/ContinuousPainter.h"
88 #include "wtf/CurrentTime.h"
89 #include "wtf/RefPtr.h"
90 #include "wtf/TemporaryChange.h"
91
92 namespace blink {
93
94 // WebFrameWidget -------------------------------------------------------------- --
95
96 WebFrameWidget* WebFrameWidget::create(WebWidgetClient* client, WebView* webView )
97 {
98 // Pass the WebFrameWidget's self-reference to the caller.
99 return WebFrameWidgetImpl::create(client, webView);
100 }
101
102 WebFrameWidgetImpl* WebFrameWidgetImpl::create(WebWidgetClient* client, WebView* webView)
103 {
104 // Pass the WebFrameWidgetImpl's self-reference to the caller.
105 return adoptRef(new WebFrameWidgetImpl(client, webView)).leakRef();
106 }
107
108 void WebFrameWidgetImpl::setLocalRoot(WebLocalFrame* frame)
109 {
110 m_localRoot = toWebLocalFrameImpl(frame);
111 m_localRoot->setFrameWidget(this);
112 }
113
114 WebFrameWidgetImpl::WebFrameWidgetImpl(WebWidgetClient* client, WebView* webView )
115 : m_client(client)
116 , m_localRoot(nullptr)
117 , m_layerTreeView(nullptr)
118 , m_rootLayer(nullptr)
119 , m_rootGraphicsLayer(nullptr)
120 , m_isAcceleratedCompositingActive(false)
121 , m_layerTreeViewClosed(false)
122 , m_page(toWebViewImpl(webView)->page())
123 , m_webView(toWebViewImpl(webView))
124 , m_suppressNextKeypressEvent(false)
125 , m_ignoreInputEvents(false)
126 {
127 initializeLayerTreeView();
128 }
129
130 WebFrameWidgetImpl::~WebFrameWidgetImpl()
131 {
132 }
133
134 // WebWidget ------------------------------------------------------------------
135
136 void WebFrameWidgetImpl::close()
137 {
138 // Reset the delegate to prevent notifications being sent as we're being
139 // deleted.
140 m_client = 0;
141
142 deref(); // Balances ref() acquired in WebFrameWidget::create
143 }
144
145 WebSize WebFrameWidgetImpl::size()
146 {
147 return m_size;
148 }
149
150 void WebFrameWidgetImpl::willStartLiveResize()
151 {
152 if (m_localRoot->frameView())
153 m_localRoot->frameView()->willStartLiveResize();
154
155 LocalFrame* frame = m_localRoot->frame();
156 WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainer FromFrame(frame);
157 if (pluginContainer)
158 pluginContainer->willStartLiveResize();
159 }
160
161 void WebFrameWidgetImpl::resize(const WebSize& newSize)
162 {
163 if (m_size == newSize)
164 return;
165
166 FrameView* view = m_localRoot->frameView();
167 if (!view)
168 return;
169
170 m_size = newSize;
171
172 updateMainFrameLayoutSize();
173
174 view->resize(m_size);
175
176 // FIXME: In WebViewImpl this layout was a precursor to setting the minimum scale limit.
177 // It is not clear if this is necessary for frame-level widget resize.
178 if (view->needsLayout())
179 view->layout();
180
181 // FIXME: Investigate whether this is needed; comment from eseidel suggests that this function
182 // is flawed.
183 sendResizeEventAndRepaint();
184 }
185
186 void WebFrameWidgetImpl::sendResizeEventAndRepaint()
187 {
188 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent
189 // as part of layout. Layout is also responsible for sending invalidations
190 // to the embedder. This method and all callers may be wrong. -- eseidel.
191 if (m_localRoot->frameView()) {
192 // Enqueues the resize event.
193 m_localRoot->frame()->document()->enqueueResizeEvent();
194 }
195
196 if (m_client) {
197 if (isAcceleratedCompositingActive()) {
198 updateLayerTreeViewport();
199 } else {
200 WebRect damagedRect(0, 0, m_size.width, m_size.height);
201 m_client->didInvalidateRect(damagedRect);
202 }
203 }
204 }
205
206 void WebFrameWidgetImpl::resizePinchViewport(const WebSize& newSize)
207 {
208 // TODO: Implement pinch viewport for out-of-process iframes.
209 }
210
211 void WebFrameWidgetImpl::updateMainFrameLayoutSize()
212 {
213 if (!m_localRoot)
214 return;
215
216 RefPtr<FrameView> view = m_localRoot->frameView();
217 if (!view)
218 return;
219
220 WebSize layoutSize = m_size;
221
222 view->setLayoutSize(layoutSize);
223 }
224
225 void WebFrameWidgetImpl::willEndLiveResize()
226 {
227 if (m_localRoot->frameView())
228 m_localRoot->frameView()->willEndLiveResize();
229
230 LocalFrame* frame = m_localRoot->frame();
231 WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainer FromFrame(frame);
232 if (pluginContainer)
233 pluginContainer->willEndLiveResize();
234 }
235
236 void WebFrameWidgetImpl::willEnterFullScreen()
237 {
238 // FIXME: Implement full screen for out-of-process iframes.
239 }
240
241 void WebFrameWidgetImpl::didEnterFullScreen()
242 {
243 // FIXME: Implement full screen for out-of-process iframes.
244 }
245
246 void WebFrameWidgetImpl::willExitFullScreen()
247 {
248 // FIXME: Implement full screen for out-of-process iframes.
249 }
250
251 void WebFrameWidgetImpl::didExitFullScreen()
252 {
253 // FIXME: Implement full screen for out-of-process iframes.
254 }
255
256 void WebFrameWidgetImpl::beginFrame(const WebBeginFrameArgs& frameTime)
257 {
258 TRACE_EVENT0("blink", "WebFrameWidgetImpl::beginFrame");
259
260 WebBeginFrameArgs validFrameTime(frameTime);
261 if (!validFrameTime.lastFrameTimeMonotonic)
262 validFrameTime.lastFrameTimeMonotonic = monotonicallyIncreasingTime();
263
264 PageWidgetDelegate::animate(*m_page, validFrameTime.lastFrameTimeMonotonic, *m_localRoot->frame());
265 }
266
267 void WebFrameWidgetImpl::layout()
268 {
269 TRACE_EVENT0("blink", "WebFrameWidgetImpl::layout");
270 if (!m_localRoot)
271 return;
272
273 PageWidgetDelegate::layout(*m_page, *m_localRoot->frame());
274 updateLayerTreeBackgroundColor();
275 }
276
277 void WebFrameWidgetImpl::paint(WebCanvas* canvas, const WebRect& rect)
278 {
279 // Out-of-process iframes require compositing.
280 ASSERT_NOT_REACHED();
281 }
282
283
284 void WebFrameWidgetImpl::updateLayerTreeViewport()
285 {
286 if (!page() || !m_layerTreeView)
287 return;
288
289 // FIXME: We need access to page scale information from the WebView.
290 m_layerTreeView->setPageScaleFactorAndLimits(1, 1, 1);
291 }
292
293 void WebFrameWidgetImpl::updateLayerTreeBackgroundColor()
294 {
295 if (!m_layerTreeView)
296 return;
297
298 m_layerTreeView->setBackgroundColor(alphaChannel(m_webView->backgroundColorO verride()) ? m_webView->backgroundColorOverride() : m_webView->backgroundColor() );
299 }
300
301 void WebFrameWidgetImpl::updateLayerTreeDeviceScaleFactor()
302 {
303 ASSERT(page());
304 ASSERT(m_layerTreeView);
305
306 float deviceScaleFactor = page()->deviceScaleFactor();
307 m_layerTreeView->setDeviceScaleFactor(deviceScaleFactor);
308 }
309
310 bool WebFrameWidgetImpl::isTransparent() const
311 {
312 // FIXME: This might need to proxy to the WebView's isTransparent().
313 return false;
314 }
315
316 void WebFrameWidgetImpl::compositeAndReadbackAsync(WebCompositeAndReadbackAsyncC allback* callback)
317 {
318 m_layerTreeView->compositeAndReadbackAsync(callback);
319 }
320
321 bool WebFrameWidgetImpl::isTrackingRepaints() const
322 {
323 return m_localRoot->frameView()->isTrackingPaintInvalidations();
324 }
325
326 void WebFrameWidgetImpl::themeChanged()
327 {
328 FrameView* view = m_localRoot->frameView();
329
330 WebRect damagedRect(0, 0, m_size.width, m_size.height);
331 view->invalidateRect(damagedRect);
332 }
333
334 const WebInputEvent* WebFrameWidgetImpl::m_currentInputEvent = 0;
335
336 // FIXME: autogenerate this kind of code, and use it throughout Blink rather tha n
337 // the one-offs for subsets of these values.
338 static String inputTypeToName(WebInputEvent::Type type)
339 {
340 switch (type) {
341 case WebInputEvent::MouseDown:
342 return EventTypeNames::mousedown;
343 case WebInputEvent::MouseUp:
344 return EventTypeNames::mouseup;
345 case WebInputEvent::MouseMove:
346 return EventTypeNames::mousemove;
347 case WebInputEvent::MouseEnter:
348 return EventTypeNames::mouseenter;
349 case WebInputEvent::MouseLeave:
350 return EventTypeNames::mouseleave;
351 case WebInputEvent::ContextMenu:
352 return EventTypeNames::contextmenu;
353 case WebInputEvent::MouseWheel:
354 return EventTypeNames::mousewheel;
355 case WebInputEvent::KeyDown:
356 return EventTypeNames::keydown;
357 case WebInputEvent::KeyUp:
358 return EventTypeNames::keyup;
359 case WebInputEvent::GestureScrollBegin:
360 return EventTypeNames::gesturescrollstart;
361 case WebInputEvent::GestureScrollEnd:
362 return EventTypeNames::gesturescrollend;
363 case WebInputEvent::GestureScrollUpdate:
364 return EventTypeNames::gesturescrollupdate;
365 case WebInputEvent::GestureTapDown:
366 return EventTypeNames::gesturetapdown;
367 case WebInputEvent::GestureShowPress:
368 return EventTypeNames::gestureshowpress;
369 case WebInputEvent::GestureTap:
370 return EventTypeNames::gesturetap;
371 case WebInputEvent::GestureTapUnconfirmed:
372 return EventTypeNames::gesturetapunconfirmed;
373 case WebInputEvent::TouchStart:
374 return EventTypeNames::touchstart;
375 case WebInputEvent::TouchMove:
376 return EventTypeNames::touchmove;
377 case WebInputEvent::TouchEnd:
378 return EventTypeNames::touchend;
379 case WebInputEvent::TouchCancel:
380 return EventTypeNames::touchcancel;
381 default:
382 return String("unknown");
383 }
384 }
385
386 bool WebFrameWidgetImpl::handleInputEvent(const WebInputEvent& inputEvent)
387 {
388
389 TRACE_EVENT1("input", "WebFrameWidgetImpl::handleInputEvent", "type", inputT ypeToName(inputEvent.type).ascii());
390
391 // Report the event to be NOT processed by WebKit, so that the browser can h andle it appropriately.
392 if (m_ignoreInputEvents)
393 return false;
394
395 TemporaryChange<const WebInputEvent*> currentEventChange(m_currentInputEvent , &inputEvent);
396
397 if (m_mouseCaptureNode && WebInputEvent::isMouseEventType(inputEvent.type)) {
398 TRACE_EVENT1("input", "captured mouse event", "type", inputEvent.type);
399 // Save m_mouseCaptureNode since mouseCaptureLost() will clear it.
400 RefPtrWillBeRawPtr<Node> node = m_mouseCaptureNode;
401
402 // Not all platforms call mouseCaptureLost() directly.
403 if (inputEvent.type == WebInputEvent::MouseUp)
404 mouseCaptureLost();
405
406 OwnPtr<UserGestureIndicator> gestureIndicator;
407
408 AtomicString eventType;
409 switch (inputEvent.type) {
410 case WebInputEvent::MouseMove:
411 eventType = EventTypeNames::mousemove;
412 break;
413 case WebInputEvent::MouseLeave:
414 eventType = EventTypeNames::mouseout;
415 break;
416 case WebInputEvent::MouseDown:
417 eventType = EventTypeNames::mousedown;
418 gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProce ssingNewUserGesture));
419 m_mouseCaptureGestureToken = gestureIndicator->currentToken();
420 break;
421 case WebInputEvent::MouseUp:
422 eventType = EventTypeNames::mouseup;
423 gestureIndicator = adoptPtr(new UserGestureIndicator(m_mouseCaptureG estureToken.release()));
424 break;
425 default:
426 ASSERT_NOT_REACHED();
427 }
428
429 node->dispatchMouseEvent(
430 PlatformMouseEventBuilder(m_localRoot->frameView(), static_cast<cons t WebMouseEvent&>(inputEvent)),
431 eventType, static_cast<const WebMouseEvent&>(inputEvent).clickCount) ;
432 return true;
433 }
434
435 return PageWidgetDelegate::handleInputEvent(*this, inputEvent, m_localRoot-> frame());
436 }
437
438 void WebFrameWidgetImpl::setCursorVisibilityState(bool isVisible)
439 {
440 if (m_page)
dcheng 2014/12/16 20:13:06 Why might page be null here and not elsewhere? Do
kenrb 2014/12/16 22:04:12 I reproduced the checks in WebViewImpl, even thoug
dcheng 2014/12/16 23:20:20 Well, we don't currently ever null out the page. S
kenrb 2014/12/17 14:52:31 Sounds good.
441 m_page->setIsCursorVisible(isVisible);
442 }
443
444 void WebFrameWidgetImpl::hasTouchEventHandlers(bool hasTouchHandlers)
445 {
446 if (m_client)
447 m_client->hasTouchEventHandlers(hasTouchHandlers);
448 }
449
450 bool WebFrameWidgetImpl::hasTouchEventHandlersAt(const WebPoint& point)
451 {
452 // FIXME: Implement this. Note that the point must be divided by pageScaleFa ctor.
453 return true;
454 }
455
456 void WebFrameWidgetImpl::scheduleAnimation()
457 {
458 if (m_layerTreeView) {
459 m_layerTreeView->setNeedsAnimate();
460 return;
461 }
462 if (m_client)
463 m_client->scheduleAnimation();
464 }
465
466 void WebFrameWidgetImpl::applyViewportDeltas(
467 const WebSize& pinchViewportDelta,
468 const WebSize& mainFrameDelta,
469 float pageScaleDelta,
470 float topControlsDelta)
471 {
472 // FIXME: To be implemented.
473 }
474
475 void WebFrameWidgetImpl::applyViewportDeltas(const WebSize& scrollDelta, float p ageScaleDelta, float topControlsDelta)
476 {
477 // FIXME: To be implemented.
478 }
479
480 void WebFrameWidgetImpl::mouseCaptureLost()
481 {
482 TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this);
483 m_mouseCaptureNode = nullptr;
484 }
485
486 void WebFrameWidgetImpl::setFocus(bool enable)
487 {
488 m_page->focusController().setFocused(enable);
489 if (enable) {
490 m_page->focusController().setActive(true);
491 RefPtr<Frame> focusedFrame = m_page->focusController().focusedFrame();
492 if (focusedFrame && focusedFrame->isLocalFrame()) {
493 LocalFrame* localFrame = toLocalFrame(focusedFrame.get());
494 Element* element = localFrame->document()->focusedElement();
495 if (element && localFrame->selection().selection().isNone()) {
496 // If the selection was cleared while the WebView was not
497 // focused, then the focus element shows with a focus ring but
498 // no caret and does respond to keyboard inputs.
499 if (element->isTextFormControl()) {
500 element->updateFocusAppearance(true);
501 } else if (element->isContentEditable()) {
502 // updateFocusAppearance() selects all the text of
503 // contentseditable DIVs. So we set the selection explicitly
504 // instead. Note that this has the side effect of moving the
505 // caret back to the beginning of the text.
506 Position position(element, 0, Position::PositionIsOffsetInAn chor);
507 localFrame->selection().setSelection(VisibleSelection(positi on, SEL_DEFAULT_AFFINITY));
508 }
509 }
510 }
511 }
512 }
513
514 bool WebFrameWidgetImpl::setComposition(
515 const WebString& text,
516 const WebVector<WebCompositionUnderline>& underlines,
517 int selectionStart,
518 int selectionEnd)
519 {
520 // FIXME: To be implemented.
521 return false;
522 }
523
524 bool WebFrameWidgetImpl::confirmComposition()
525 {
526 // FIXME: To be implemented.
527 return false;
528 }
529
530 bool WebFrameWidgetImpl::confirmComposition(ConfirmCompositionBehavior selection Behavior)
531 {
532 // FIXME: To be implemented.
533 return false;
534 }
535
536 bool WebFrameWidgetImpl::confirmComposition(const WebString& text)
537 {
538 // FIXME: To be implemented.
539 return false;
540 }
541
542 bool WebFrameWidgetImpl::compositionRange(size_t* location, size_t* length)
543 {
544 // FIXME: To be implemented.
545 return false;
546 }
547
548 WebTextInputInfo WebFrameWidgetImpl::textInputInfo()
549 {
550 WebTextInputInfo info;
551 // FIXME: To be implemented.
552 return info;
553 }
554
555 WebColor WebFrameWidgetImpl::backgroundColor() const
556 {
557 if (isTransparent())
558 return Color::transparent;
559 if (!m_localRoot->frameView())
560 return m_webView->backgroundColor();
561 FrameView* view = m_localRoot->frameView();
562 return view->documentBackgroundColor().rgb();
563 }
564
565 bool WebFrameWidgetImpl::selectionBounds(WebRect& anchor, WebRect& focus) const
566 {
567 const Frame* frame = focusedCoreFrame();
568 if (!frame || !frame->isLocalFrame())
569 return false;
570
571 const LocalFrame* localFrame = toLocalFrame(frame);
572 if (!localFrame)
573 return false;
574 FrameSelection& selection = localFrame->selection();
575
576 if (selection.isCaret()) {
577 anchor = focus = selection.absoluteCaretBounds();
578 } else {
579 RefPtrWillBeRawPtr<Range> selectedRange = selection.toNormalizedRange();
580 if (!selectedRange)
581 return false;
582
583 RefPtrWillBeRawPtr<Range> range(Range::create(selectedRange->startContai ner()->document(),
584 selectedRange->startContainer(),
585 selectedRange->startOffset(),
586 selectedRange->startContainer(),
587 selectedRange->startOffset()));
588 anchor = localFrame->editor().firstRectForRange(range.get());
589
590 range = Range::create(selectedRange->endContainer()->document(),
591 selectedRange->endContainer(),
592 selectedRange->endOffset(),
593 selectedRange->endContainer(),
594 selectedRange->endOffset());
595 focus = localFrame->editor().firstRectForRange(range.get());
596 }
597
598 IntRect scaledAnchor(localFrame->view()->contentsToWindow(anchor));
599 IntRect scaledFocus(localFrame->view()->contentsToWindow(focus));
600
601 anchor = scaledAnchor;
602 focus = scaledFocus;
603
604 if (!selection.selection().isBaseFirst())
605 std::swap(anchor, focus);
606 return true;
607 }
608
609 bool WebFrameWidgetImpl::selectionTextDirection(WebTextDirection& start, WebText Direction& end) const
610 {
611 if (!focusedCoreFrame()->isLocalFrame())
612 return false;
613 const LocalFrame* frame = toLocalFrame(focusedCoreFrame());
614 if (!frame)
615 return false;
616 FrameSelection& selection = frame->selection();
617 if (!selection.toNormalizedRange())
618 return false;
619 start = toWebTextDirection(selection.start().primaryDirection());
620 end = toWebTextDirection(selection.end().primaryDirection());
621 return true;
622 }
623
624 bool WebFrameWidgetImpl::isSelectionAnchorFirst() const
625 {
626 if (!focusedCoreFrame()->isLocalFrame())
627 return false;
628 if (const LocalFrame* frame = toLocalFrame(focusedCoreFrame()))
629 return frame->selection().selection().isBaseFirst();
630 return false;
631 }
632
633 bool WebFrameWidgetImpl::caretOrSelectionRange(size_t* location, size_t* length)
634 {
635 if (!focusedCoreFrame()->isLocalFrame())
636 return false;
637 const LocalFrame* focused = toLocalFrame(focusedCoreFrame());
638 if (!focused)
639 return false;
640
641 PlainTextRange selectionOffsets = focused->inputMethodController().getSelect ionOffsets();
642 if (selectionOffsets.isNull())
643 return false;
644
645 *location = selectionOffsets.start();
646 *length = selectionOffsets.length();
647 return true;
648 }
649
650 void WebFrameWidgetImpl::setTextDirection(WebTextDirection direction)
651 {
652 // The Editor::setBaseWritingDirection() function checks if we can change
653 // the text direction of the selected node and updates its DOM "dir"
654 // attribute and its CSS "direction" property.
655 // So, we just call the function as Safari does.
656 if (!focusedCoreFrame()->isLocalFrame())
657 return;
658 const LocalFrame* focused = toLocalFrame(focusedCoreFrame());
659 if (!focused)
660 return;
661
662 Editor& editor = focused->editor();
663 if (!editor.canEdit())
664 return;
665
666 switch (direction) {
667 case WebTextDirectionDefault:
668 editor.setBaseWritingDirection(NaturalWritingDirection);
669 break;
670
671 case WebTextDirectionLeftToRight:
672 editor.setBaseWritingDirection(LeftToRightWritingDirection);
673 break;
674
675 case WebTextDirectionRightToLeft:
676 editor.setBaseWritingDirection(RightToLeftWritingDirection);
677 break;
678
679 default:
680 notImplemented();
681 break;
682 }
683 }
684
685 bool WebFrameWidgetImpl::isAcceleratedCompositingActive() const
686 {
687 return m_isAcceleratedCompositingActive;
688 }
689
690 void WebFrameWidgetImpl::willCloseLayerTreeView()
691 {
692 setIsAcceleratedCompositingActive(false);
693 m_layerTreeView = 0;
694 m_layerTreeViewClosed = true;
695 }
696
697 void WebFrameWidgetImpl::didChangeWindowResizerRect()
698 {
699 if (m_localRoot->frameView())
700 m_localRoot->frameView()->windowResizerRectChanged();
701 }
702
703 void WebFrameWidgetImpl::handleMouseLeave(LocalFrame& mainFrame, const WebMouseE vent& event)
704 {
705 // FIXME: WebWidget doesn't have the method below.
706 // m_client->setMouseOverURL(WebURL());
707 PageWidgetEventHandler::handleMouseLeave(mainFrame, event);
708 }
709
710 void WebFrameWidgetImpl::handleMouseDown(LocalFrame& mainFrame, const WebMouseEv ent& event)
711 {
712 // Take capture on a mouse down on a plugin so we can send it mouse events.
713 // If the hit node is a plugin but a scrollbar is over it don't start mouse
714 // capture because it will interfere with the scrollbar receiving events.
715 IntPoint point(event.x, event.y);
716 if (event.button == WebMouseEvent::ButtonLeft) {
717 point = m_localRoot->frameView()->windowToContents(point);
718 HitTestResult result(m_localRoot->frame()->eventHandler().hitTestResultA tPoint(point));
719 result.setToShadowHostIfInUserAgentShadowRoot();
720 Node* hitNode = result.innerNonSharedNode();
721
722 if (!result.scrollbar() && hitNode && hitNode->renderer() && hitNode->re nderer()->isEmbeddedObject()) {
723 m_mouseCaptureNode = hitNode;
724 TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this);
725 }
726 }
727
728 PageWidgetEventHandler::handleMouseDown(mainFrame, event);
729
730 if (event.button == WebMouseEvent::ButtonLeft && m_mouseCaptureNode)
731 m_mouseCaptureGestureToken = mainFrame.eventHandler().takeLastMouseDownG estureToken();
732
733 // FIXME: Add context menu support.
734 }
735
736 void WebFrameWidgetImpl::handleMouseUp(LocalFrame& mainFrame, const WebMouseEven t& event)
737 {
738 PageWidgetEventHandler::handleMouseUp(mainFrame, event);
739
740 // FIXME: Add context menu support (Windows).
741 }
742
743 bool WebFrameWidgetImpl::handleMouseWheel(LocalFrame& mainFrame, const WebMouseW heelEvent& event)
744 {
745 return PageWidgetEventHandler::handleMouseWheel(mainFrame, event);
746 }
747
748 bool WebFrameWidgetImpl::handleGestureEvent(const WebGestureEvent& event)
749 {
750 // FIXME: Add gesture support.
751 return false;
752 }
753
754 bool WebFrameWidgetImpl::handleKeyEvent(const WebKeyboardEvent& event)
755 {
756 ASSERT((event.type == WebInputEvent::RawKeyDown)
757 || (event.type == WebInputEvent::KeyDown)
758 || (event.type == WebInputEvent::KeyUp));
759
760 // Please refer to the comments explaining the m_suppressNextKeypressEvent
761 // member.
762 // The m_suppressNextKeypressEvent is set if the KeyDown is handled by
763 // Webkit. A keyDown event is typically associated with a keyPress(char)
764 // event and a keyUp event. We reset this flag here as this is a new keyDown
765 // event.
766 m_suppressNextKeypressEvent = false;
767
768 RefPtr<Frame> focusedFrame = focusedCoreFrame();
769 if (focusedFrame && focusedFrame->isRemoteFrame()) {
770 WebRemoteFrameImpl* webFrame = WebRemoteFrameImpl::fromFrame(*toRemoteFr ame(focusedFrame.get()));
771 webFrame->client()->forwardInputEvent(&event);
772 return true;
773 }
774
775 if (!focusedFrame || !focusedFrame->isLocalFrame())
776 return false;
777
778 RefPtr<LocalFrame> frame = toLocalFrame(focusedFrame.get());
779
780 PlatformKeyboardEventBuilder evt(event);
781
782 if (frame->eventHandler().keyEvent(evt)) {
783 if (WebInputEvent::RawKeyDown == event.type) {
784 // Suppress the next keypress event unless the focused node is a plu g-in node.
785 // (Flash needs these keypress events to handle non-US keyboards.)
786 Element* element = focusedElement();
787 if (!element || !element->renderer() || !element->renderer()->isEmbe ddedObject())
788 m_suppressNextKeypressEvent = true;
789 }
790 return true;
791 }
792
793 return keyEventDefault(event);
794 }
795
796 bool WebFrameWidgetImpl::handleCharEvent(const WebKeyboardEvent& event)
797 {
798 ASSERT(event.type == WebInputEvent::Char);
799
800 // Please refer to the comments explaining the m_suppressNextKeypressEvent
801 // member. The m_suppressNextKeypressEvent is set if the KeyDown is
802 // handled by Webkit. A keyDown event is typically associated with a
803 // keyPress(char) event and a keyUp event. We reset this flag here as it
804 // only applies to the current keyPress event.
805 bool suppress = m_suppressNextKeypressEvent;
806 m_suppressNextKeypressEvent = false;
807
808 LocalFrame* frame = toLocalFrame(focusedCoreFrame());
809 if (!frame)
810 return suppress;
811
812 EventHandler& handler = frame->eventHandler();
813
814 PlatformKeyboardEventBuilder evt(event);
815 if (!evt.isCharacterKey())
816 return true;
817
818 // Accesskeys are triggered by char events and can't be suppressed.
819 if (handler.handleAccessKey(evt))
820 return true;
821
822 // Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
823 // the eventHandler::keyEvent. We mimic this behavior on all platforms since
824 // for now we are converting other platform's key events to windows key
825 // events.
826 if (evt.isSystemKey())
827 return false;
828
829 if (!suppress && !handler.keyEvent(evt))
830 return keyEventDefault(event);
831
832 return true;
833 }
834
835
836 bool WebFrameWidgetImpl::keyEventDefault(const WebKeyboardEvent& event)
837 {
838 LocalFrame* frame = toLocalFrame(focusedCoreFrame());
839 if (!frame)
840 return false;
841
842 switch (event.type) {
843 case WebInputEvent::Char:
844 if (event.windowsKeyCode == VKEY_SPACE) {
845 int keyCode = ((event.modifiers & WebInputEvent::ShiftKey) ? VKEY_PR IOR : VKEY_NEXT);
846 return scrollViewWithKeyboard(keyCode, event.modifiers);
847 }
848 break;
849 case WebInputEvent::RawKeyDown:
850 if (event.modifiers == WebInputEvent::ControlKey) {
851 switch (event.windowsKeyCode) {
852 #if !OS(MACOSX)
853 case 'A':
854 WebFrame::fromFrame(focusedCoreFrame())->executeCommand(WebStrin g::fromUTF8("SelectAll"));
855 return true;
856 case VKEY_INSERT:
857 case 'C':
858 WebFrame::fromFrame(focusedCoreFrame())->executeCommand(WebStrin g::fromUTF8("Copy"));
859 return true;
860 #endif
861 // Match FF behavior in the sense that Ctrl+home/end are the only Ct rl
862 // key combinations which affect scrolling. Safari is buggy in the
863 // sense that it scrolls the page for all Ctrl+scrolling key
864 // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
865 case VKEY_HOME:
866 case VKEY_END:
867 break;
868 default:
869 return false;
870 }
871 }
872 if (!event.isSystemKey && !(event.modifiers & WebInputEvent::ShiftKey))
873 return scrollViewWithKeyboard(event.windowsKeyCode, event.modifiers) ;
874 break;
875 default:
876 break;
877 }
878 return false;
879 }
880
881 bool WebFrameWidgetImpl::scrollViewWithKeyboard(int keyCode, int modifiers)
882 {
883 ScrollDirection scrollDirection;
884 ScrollGranularity scrollGranularity;
885 #if OS(MACOSX)
886 // Control-Up/Down should be PageUp/Down on Mac.
887 if (modifiers & WebMouseEvent::ControlKey) {
888 if (keyCode == VKEY_UP)
889 keyCode = VKEY_PRIOR;
890 else if (keyCode == VKEY_DOWN)
891 keyCode = VKEY_NEXT;
892 }
893 #endif
894 if (!mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity))
895 return false;
896
897 if (LocalFrame* frame = toLocalFrame(focusedCoreFrame()))
898 return frame->eventHandler().bubblingScroll(scrollDirection, scrollGranu larity);
899 return false;
900 }
901
902 bool WebFrameWidgetImpl::mapKeyCodeForScroll(
903 int keyCode,
904 ScrollDirection* scrollDirection,
905 ScrollGranularity* scrollGranularity)
906 {
907 switch (keyCode) {
908 case VKEY_LEFT:
909 *scrollDirection = ScrollLeft;
910 *scrollGranularity = ScrollByLine;
911 break;
912 case VKEY_RIGHT:
913 *scrollDirection = ScrollRight;
914 *scrollGranularity = ScrollByLine;
915 break;
916 case VKEY_UP:
917 *scrollDirection = ScrollUp;
918 *scrollGranularity = ScrollByLine;
919 break;
920 case VKEY_DOWN:
921 *scrollDirection = ScrollDown;
922 *scrollGranularity = ScrollByLine;
923 break;
924 case VKEY_HOME:
925 *scrollDirection = ScrollUp;
926 *scrollGranularity = ScrollByDocument;
927 break;
928 case VKEY_END:
929 *scrollDirection = ScrollDown;
930 *scrollGranularity = ScrollByDocument;
931 break;
932 case VKEY_PRIOR: // page up
933 *scrollDirection = ScrollUp;
934 *scrollGranularity = ScrollByPage;
935 break;
936 case VKEY_NEXT: // page down
937 *scrollDirection = ScrollDown;
938 *scrollGranularity = ScrollByPage;
939 break;
940 default:
941 return false;
942 }
943
944 return true;
945 }
946
947 Frame* WebFrameWidgetImpl::focusedCoreFrame() const
948 {
949 return m_page ? m_page->focusController().focusedOrMainFrame() : 0;
950 }
951
952 Element* WebFrameWidgetImpl::focusedElement() const
953 {
954 Frame* frame = m_page->focusController().focusedFrame();
955 if (!frame || !frame->isLocalFrame())
956 return 0;
957
958 Document* document = toLocalFrame(frame)->document();
959 if (!document)
960 return 0;
961
962 return document->focusedElement();
963 }
964
965 void WebFrameWidgetImpl::initializeLayerTreeView()
966 {
967 if (m_client) {
968 m_client->initializeLayerTreeView();
969 m_layerTreeView = m_client->layerTreeView();
970 }
971
972 m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView != 0);
973
974 // FIXME: only unittests, click to play, Android priting, and printing (for headers and footers)
975 // make this assert necessary. We should make them not hit this code and the n delete allowsBrokenNullLayerTreeView.
976 ASSERT(m_layerTreeView || !m_client || m_client->allowsBrokenNullLayerTreeVi ew());
977 }
978
979 void WebFrameWidgetImpl::setIsAcceleratedCompositingActive(bool active)
980 {
981 // In the middle of shutting down; don't try to spin back up a compositor.
982 // FIXME: compositing startup/shutdown should be refactored so that it
983 // turns on explicitly rather than lazily, which causes this awkwardness.
984 if (m_layerTreeViewClosed)
985 return;
986
987 ASSERT(!active || m_layerTreeView);
988
989 if (m_isAcceleratedCompositingActive == active)
990 return;
991
992 if (!m_client)
993 return;
994
995 if (active) {
996 TRACE_EVENT0("blink", "WebViewImpl::setIsAcceleratedCompositingActive(tr ue)");
997 m_layerTreeView->setRootLayer(*m_rootLayer);
998
999 bool visible = page()->visibilityState() == PageVisibilityStateVisible;
1000 m_layerTreeView->setVisible(visible);
1001 updateLayerTreeDeviceScaleFactor();
1002 updateLayerTreeBackgroundColor();
1003 m_layerTreeView->setHasTransparentBackground(isTransparent());
1004 updateLayerTreeViewport();
1005 m_isAcceleratedCompositingActive = true;
1006 }
1007 if (m_localRoot->frameView())
1008 m_localRoot->frameView()->setClipsRepaints(!m_isAcceleratedCompositingAc tive);
1009 }
1010
1011 RenderLayerCompositor* WebFrameWidgetImpl::compositor() const
1012 {
1013 LocalFrame* frame = toLocalFrame(toCoreFrame(m_localRoot));
1014 if (!frame || !frame->document() || !frame->document()->renderView())
1015 return 0;
1016
1017 return frame->document()->renderView()->compositor();
1018 }
1019
1020 void WebFrameWidgetImpl::suppressInvalidations(bool enable)
1021 {
1022 if (m_client)
1023 m_client->suppressCompositorScheduling(enable);
1024 }
1025
1026 void WebFrameWidgetImpl::setRootGraphicsLayer(GraphicsLayer* layer)
1027 {
1028 suppressInvalidations(true);
1029
1030 m_rootGraphicsLayer = layer;
1031 m_rootLayer = layer ? layer->platformLayer() : 0;
1032
1033 setIsAcceleratedCompositingActive(layer != 0);
1034
1035 if (m_layerTreeView) {
1036 if (m_rootLayer) {
1037 m_layerTreeView->setRootLayer(*m_rootLayer);
1038 // We register viewport layers here since there may not be a layer
1039 // tree view prior to this point.
1040 GraphicsLayer* rootScrollLayer = compositor()->scrollLayer();
1041 ASSERT(rootScrollLayer);
1042 WebLayer* pageScaleLayer = rootScrollLayer->parent() ? rootScrollLay er->parent()->platformLayer() : 0;
1043 m_layerTreeView->registerViewportLayers(0, pageScaleLayer, rootScrol lLayer->platformLayer(), 0);
1044 } else {
1045 m_layerTreeView->clearRootLayer();
1046 m_layerTreeView->clearViewportLayers();
1047 }
1048 }
1049
1050 suppressInvalidations(false);
1051 }
1052
1053 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698