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

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

Powered by Google App Engine
This is Rietveld 408576698