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

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

Powered by Google App Engine
This is Rietveld 408576698