summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
blob: 64a22db62dba5c8bc15f08bf19bedf73330f2d57 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_VIEW_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_VIEW_IMPL_H_

#include <memory>

#include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "cc/input/overscroll_behavior.h"
#include "third_party/blink/public/common/manifest/web_display_mode.h"
#include "third_party/blink/public/platform/web_float_size.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_input_event_result.h"
#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_page_importance_signals.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/exported/web_page_popup_impl.h"
#include "third_party/blink/renderer/core/frame/resize_viewport_anchor.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/context_menu_provider.h"
#include "third_party/blink/renderer/core/page/event_with_hit_test_results.h"
#include "third_party/blink/renderer/core/page/page_widget_delegate.h"
#include "third_party/blink/renderer/core/page/scoped_page_pauser.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/apply_viewport_changes.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
#include "third_party/blink/renderer/platform/graphics/touch_action.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace cc {
class Layer;
class ScopedDeferMainFrameUpdate;
}

namespace blink {
class BrowserControls;
class DevToolsEmulator;
class Frame;
class FullscreenController;
class HTMLPlugInElement;
class PageScaleConstraintsSet;
class PaintLayerCompositor;
class UserGestureToken;
class WebDevToolsAgentImpl;
class WebElement;
class WebInputMethodController;
class WebLayerTreeView;
class WebLocalFrame;
class WebLocalFrameImpl;
class WebRemoteFrame;
class WebSettingsImpl;
class WebViewClient;
class WebWidgetClient;

class CORE_EXPORT WebViewImpl final : public WebView,
                                      private WebWidget,
                                      public RefCounted<WebViewImpl>,
                                      public PageWidgetEventHandler {
 public:
  static WebViewImpl* Create(WebViewClient*,
                             bool is_hidden,
                             bool compositing_enabled,
                             WebViewImpl* opener);
  static HashSet<WebViewImpl*>& AllInstances();
  // Returns true if popup menus should be rendered by the browser, false if
  // they should be rendered by WebKit (which is the default).
  static bool UseExternalPopupMenus();

  // Returns whether frames under this WebView are backed by a compositor. When
  // false there may be no WebWidgetClient present. When true, there must be a
  // WebWidgetClient while a local main frame is attached.
  bool does_composite() const { return does_composite_; }

  // WebView methods:
  void DidAttachLocalMainFrame(WebWidgetClient*) override;
  void DidAttachRemoteMainFrame(WebWidgetClient*) override;
  void SetPrerendererClient(WebPrerendererClient*) override;
  WebSettings* GetSettings() override;
  WebString PageEncoding() const override;
  bool TabsToLinks() const override;
  void SetTabsToLinks(bool value) override;
  bool TabKeyCyclesThroughElements() const override;
  void SetTabKeyCyclesThroughElements(bool value) override;
  bool IsActive() const override;
  void SetIsActive(bool value) override;
  void SetDomainRelaxationForbidden(bool, const WebString& scheme) override;
  void SetWindowFeatures(const WebWindowFeatures&) override;
  void SetOpenedByDOM() override;
  void ResizeWithBrowserControls(const WebSize&,
                                 float top_controls_height,
                                 float bottom_controls_height,
                                 bool browser_controls_shrink_layout) override;
  WebFrame* MainFrame() override;
  WebLocalFrame* FocusedFrame() override;
  void SetFocusedFrame(WebFrame*) override;
  void FocusDocumentView(WebFrame*) override;
  void SetInitialFocus(bool reverse) override;
  void ClearFocusedElement() override;
  void SmoothScroll(int target_x, int target_y, uint64_t duration_ms) override;
  void AdvanceFocus(bool reverse) override;
  void AdvanceFocusAcrossFrames(WebFocusType,
                                WebRemoteFrame* from,
                                WebLocalFrame* to) override;
  double ZoomLevel() override;
  double SetZoomLevel(double) override;
  void ZoomLimitsChanged(double minimum_zoom_level,
                         double maximum_zoom_level) override;
  float TextZoomFactor() override;
  float SetTextZoomFactor(float) override;
  float PageScaleFactor() const override;
  float MinimumPageScaleFactor() const override;
  float MaximumPageScaleFactor() const override;
  void SetDefaultPageScaleLimits(float min_scale, float max_scale) override;
  void SetInitialPageScaleOverride(float) override;
  void SetMaximumLegibleScale(float) override;
  void SetPageScaleFactor(float) override;
  void SetVisualViewportOffset(const WebFloatPoint&) override;
  WebFloatPoint VisualViewportOffset() const override;
  WebFloatSize VisualViewportSize() const override;
  void ResetScrollAndScaleState() override;
  void SetIgnoreViewportTagScaleLimits(bool) override;
  WebSize ContentsPreferredMinimumSize() override;
  void SetDisplayMode(WebDisplayMode) override;
  void AnimateDoubleTapZoom(const gfx::Point&,
                            const WebRect& block_bounds) override;
  void ZoomToFindInPageRect(const WebRect&) override;
  void SetDeviceScaleFactor(float) override;
  void SetZoomFactorForDeviceScaleFactor(float) override;
  float ZoomFactorForDeviceScaleFactor() override {
    return zoom_factor_for_device_scale_factor_;
  }
  void EnableAutoResizeMode(const WebSize& min_size,
                            const WebSize& max_size) override;
  void DisableAutoResizeMode() override;
  void PerformPluginAction(const WebPluginAction&, const gfx::Point&) override;
  void AudioStateChanged(bool is_audio_playing) override;
  WebHitTestResult HitTestResultAt(const gfx::Point&) override;
  WebHitTestResult HitTestResultForTap(const gfx::Point&,
                                       const WebSize&) override;
  uint64_t CreateUniqueIdentifierForRequest() override;
  void EnableDeviceEmulation(const WebDeviceEmulationParams&) override;
  void DisableDeviceEmulation() override;
  void SetSelectionColors(unsigned active_background_color,
                          unsigned active_foreground_color,
                          unsigned inactive_background_color,
                          unsigned inactive_foreground_color) override;
  void PerformCustomContextMenuAction(unsigned action) override;
  void DidCloseContextMenu() override;
  void CancelPagePopup() override;
  WebPagePopupImpl* GetPagePopup() const override { return page_popup_.get(); }
  void SetMainFrameOverlayColor(SkColor) override;
  WebPageImportanceSignals* PageImportanceSignals() override;
  void AcceptLanguagesChanged() override;
  void SetPageFrozen(bool frozen) override;
  WebWidget* MainFrameWidget() override;
  void SetBaseBackgroundColor(SkColor) override;
  void SetBackgroundColorOverride(SkColor) override;
  void ClearBackgroundColorOverride() override;
  void SetBaseBackgroundColorOverride(SkColor) override;
  void ClearBaseBackgroundColorOverride() override;
  void SetInsidePortal(bool inside_portal) override;
  void PaintContent(cc::PaintCanvas*, const gfx::Rect&) override;

  void DidUpdateFullscreenSize();

  float DefaultMinimumPageScaleFactor() const;
  float DefaultMaximumPageScaleFactor() const;
  float ClampPageScaleFactorToLimits(float) const;
  void ResetScaleStateImmediately();

  HitTestResult CoreHitTestResultAt(const gfx::Point&);
  void InvalidateRect(const IntRect&);

  void SetZoomFactorOverride(float);
  void SetCompositorDeviceScaleFactorOverride(float);
  void SetDeviceEmulationTransform(const TransformationMatrix&);
  TransformationMatrix GetDeviceEmulationTransform() const;

  SkColor BackgroundColor() const;
  Color BaseBackgroundColor() const;
  bool BackgroundColorOverrideEnabled() const {
    return background_color_override_enabled_;
  }
  SkColor BackgroundColorOverride() const { return background_color_override_; }

  Frame* FocusedCoreFrame() const;

  // Returns the currently focused Element or null if no element has focus.
  Element* FocusedElement() const;

  WebViewClient* Client() { return AsView().client; }
  // TODO(dcheng): This client should be acquirable from the MainFrameImpl
  // in some cases? We need to know how to get it in all cases.
  WebWidgetClient* WidgetClient() { return AsWidget().client; }

  // Returns the page object associated with this view. This may be null when
  // the page is shutting down, but will be valid at all other times.
  Page* GetPage() const { return AsView().page.Get(); }

  WebDevToolsAgentImpl* MainFrameDevToolsAgentImpl();

  DevToolsEmulator* GetDevToolsEmulator() const {
    return dev_tools_emulator_.Get();
  }

  // Returns the main frame associated with this view. This will be null when
  // the main frame is remote.
  // Internally during startup/shutdown this can be null when no main frame
  // (local or remote) is attached, but this should not generally matter to code
  // outside this class.
  WebLocalFrameImpl* MainFrameImpl() const;

  // Event related methods:
  void MouseContextMenu(const WebMouseEvent&);
  void MouseDoubleClick(const WebMouseEvent&);

  bool StartPageScaleAnimation(const IntPoint& target_position,
                               bool use_anchor,
                               float new_scale,
                               double duration_in_seconds);

  // Handles context menu events orignated via the the keyboard. These
  // include the VK_APPS virtual key and the Shift+F10 combine. Code is
  // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM
  // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only
  // significant change in this function is the code to convert from a
  // Keyboard event to the Right Mouse button down event.
  WebInputEventResult SendContextMenuEvent();

  void ShowContextMenuForElement(WebElement);

  // Notifies the WebView that a load has been committed. isNewNavigation
  // will be true if a new session history item should be created for that
  // load. isNavigationWithinPage will be true if the navigation does
  // not take the user away from the current page.
  void DidCommitLoad(bool is_new_navigation, bool is_navigation_within_page);

  // Indicates two things:
  //   1) This view may have a new layout now.
  //   2) Layout is up-to-date.
  // After calling WebWidget::updateAllLifecyclePhases(), expect to get this
  // notification unless the view did not need a layout.
  void MainFrameLayoutUpdated();
  void ResizeAfterLayout();

  void DidChangeContentsSize();
  void PageScaleFactorChanged();
  void MainFrameScrollOffsetChanged();

  bool ShouldAutoResize() const { return should_auto_resize_; }

  IntSize MinAutoSize() const { return min_auto_size_; }

  IntSize MaxAutoSize() const { return max_auto_size_; }

  void UpdateMainFrameLayoutSize();
  void UpdatePageDefinedViewportConstraints(const ViewportDescription&);

  WebPagePopupImpl* OpenPagePopup(PagePopupClient*);
  bool HasOpenedPopup() const { return page_popup_.get(); }
  void ClosePagePopup(PagePopup*);
  // Callback from PagePopup when it is closed, which it can be done directly
  // without coming through WebViewImpl.
  void CleanupPagePopup();
  LocalDOMWindow* PagePopupWindow() const;

  GraphicsLayer* RootGraphicsLayer();
  void RegisterViewportLayersWithCompositor();
  PaintLayerCompositor* Compositor() const;

  PageScheduler* Scheduler() const override;
  void SetIsHidden(bool hidden, bool is_initial_state) override;
  bool IsHidden() override;

  // Called by a full frame plugin inside this view to inform it that its
  // zoom level has been updated.  The plugin should only call this function
  // if the zoom change was triggered by the browser, it's only needed in case
  // a plugin can update its own zoom, say because of its own UI.
  void FullFramePluginZoomLevelChanged(double zoom_level);

  void ComputeScaleAndScrollForBlockRect(
      const gfx::Point& hit_point,
      const WebRect& block_rect,
      float padding,
      float default_scale_when_already_legible,
      float& scale,
      IntPoint& scroll);
  Node* BestTapNode(const GestureEventWithHitTestResults& targeted_tap_event);
  void EnableTapHighlightAtPoint(
      const GestureEventWithHitTestResults& targeted_tap_event);
  void EnableTapHighlights(HeapVector<Member<Node>>&);

  void EnableFakePageScaleAnimationForTesting(bool);
  bool FakeDoubleTapAnimationPendingForTesting() const {
    return double_tap_zoom_pending_;
  }
  IntPoint FakePageScaleAnimationTargetPositionForTesting() const {
    return fake_page_scale_animation_target_position_;
  }
  float FakePageScaleAnimationPageScaleForTesting() const {
    return fake_page_scale_animation_page_scale_factor_;
  }
  bool FakePageScaleAnimationUseAnchorForTesting() const {
    return fake_page_scale_animation_use_anchor_;
  }

  void EnterFullscreen(LocalFrame&, const FullscreenOptions*);
  void ExitFullscreen(LocalFrame&);
  void FullscreenElementChanged(Element* old_element, Element* new_element);

  // Sends a request to the main frame's view to resize, and updates the page
  // scale limits if needed.
  void SendResizeEventForMainFrame();

  // Exposed for testing purposes.
  bool HasHorizontalScrollbar();
  bool HasVerticalScrollbar();

  WebSettingsImpl* SettingsImpl();

  WebLayerTreeView* LayerTreeView() const { return layer_tree_view_; }
  cc::AnimationHost* AnimationHost() const { return animation_host_; }

  BrowserControls& GetBrowserControls();
  // Called anytime browser controls layout height or content offset have
  // changed.
  void DidUpdateBrowserControls();

  void ForceNextWebGLContextCreationToFail() override;
  void ForceNextDrawingBufferCreationToFail() override;

  void AddAutoplayFlags(int32_t) override;
  void ClearAutoplayFlags() override;
  int32_t AutoplayFlagsForTest() override;

  IntSize MainFrameSize();
  WebDisplayMode DisplayMode() const { return display_mode_; }

  PageScaleConstraintsSet& GetPageScaleConstraintsSet() const;

  FloatSize ElasticOverscroll() const { return elastic_overscroll_; }

  class ChromeClient& GetChromeClient() const {
    return *chrome_client_.Get();
  }

  // Returns the currently active WebInputMethodController which is the one
  // corresponding to the focused frame. It will return nullptr if there is no
  // focused frame, or if the there is one but it belongs to a different local
  // root.
  WebInputMethodController* GetActiveWebInputMethodController() const;

  bool ShouldZoomToLegibleScale(const Element&);
  void ZoomAndScrollToFocusedEditableElementRect(
      const IntRect& element_bounds_in_document,
      const IntRect& caret_bounds_in_document,
      bool zoom_into_legible_scale);

  void StopDeferringMainFrameUpdate() {
    scoped_defer_main_frame_update_.reset();
  }

  // This function checks the element ids of ScrollableAreas only and returns
  // the equivalent DOM Node if such exists.
  Node* FindNodeFromScrollableCompositorElementId(
      cc::ElementId element_id) const;

  void DeferMainFrameUpdateForTesting();

  void StartDeferringCommits(base::TimeDelta timeout);
  void StopDeferringCommits();

 private:
  FRIEND_TEST_ALL_PREFIXES(WebFrameTest, DivScrollIntoEditableTest);
  FRIEND_TEST_ALL_PREFIXES(WebFrameTest,
                           DivScrollIntoEditablePreservePageScaleTest);
  FRIEND_TEST_ALL_PREFIXES(WebFrameTest,
                           DivScrollIntoEditableTestZoomToLegibleScaleDisabled);
  FRIEND_TEST_ALL_PREFIXES(WebFrameTest,
                           DivScrollIntoEditableTestWithDeviceScaleFactor);

  // TODO(danakj): DCHECK in these that we're not inside a wrong API stackframe.
  struct ViewData;
  ViewData& AsView() { return as_view_; }
  const ViewData& AsView() const { return as_view_; }
  struct WidgetData;
  WidgetData& AsWidget() { return as_widget_; }
  const WidgetData& AsWidget() const { return as_widget_; }

  // WebWidget methods:
  void SetLayerTreeView(WebLayerTreeView*, cc::AnimationHost*) override;
  void Close() override;
  WebSize Size() override;
  void Resize(const WebSize&) override;
  void ResizeVisualViewport(const WebSize&) override;
  void DidEnterFullscreen() override;
  void DidExitFullscreen() override;
  void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) override;
  void BeginFrame(base::TimeTicks last_frame_time,
                  bool record_main_frame_metrics) override;
  void DidBeginFrame() override;
  void BeginRafAlignedInput() override;
  void EndRafAlignedInput() override;
  void BeginUpdateLayers() override;
  void EndUpdateLayers() override;
  void BeginCommitCompositorFrame() override;
  void EndCommitCompositorFrame() override;
  void RecordStartOfFrameMetrics() override;
  void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override;
  void UpdateLifecycle(LifecycleUpdate requested_update,
                       LifecycleUpdateReason reason) override;
  void ThemeChanged() override;
  WebInputEventResult HandleInputEvent(const WebCoalescedInputEvent&) override;
  WebInputEventResult DispatchBufferedTouchEvents() override;
  void SetCursorVisibilityState(bool is_visible) override;
  void OnFallbackCursorModeToggled(bool is_on) override;
  void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override;
  void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
                                         bool has_scrolled_by_touch) override;
  void SendOverscrollEventFromImplSide(
      const gfx::Vector2dF& overscroll_delta,
      cc::ElementId scroll_latched_element_id) override;
  void SendScrollEndEventFromImplSide(
      cc::ElementId scroll_latched_element_id) override;
  void MouseCaptureLost() override;
  void SetFocus(bool enable) override;
  bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
  bool IsAcceleratedCompositingActive() const override;
  void DidAcquirePointerLock() override;
  void DidNotAcquirePointerLock() override;
  void DidLosePointerLock() override;
  void ShowContextMenu(WebMenuSourceType) override;
  WebURL GetURLForDebugTrace() override;

  void SetPageScaleFactorAndLocation(float scale,
                                     bool is_pinch_gesture_active,
                                     const FloatPoint&);
  void PropagateZoomFactorToLocalFrameRoots(Frame*, float);

  float MaximumLegiblePageScale() const;
  void RefreshPageScaleFactor();
  IntSize ContentsSize() const;

  void UpdateBrowserControlsConstraint(cc::BrowserControlsState constraint);
  void UpdateICBAndResizeViewport();
  void ResizeViewWhileAnchored(float top_controls_height,
                               float bottom_controls_height,
                               bool browser_controls_shrink_layout);

  void UpdateBaseBackgroundColor();

  friend class WebView;  // So WebView::Create can call our constructor
  friend class WebViewFrameWidget;
  friend class WTF::RefCounted<WebViewImpl>;
  friend class SimCompositor;

  WebViewImpl(WebViewClient*,
              bool is_hidden,
              bool does_composite,
              WebViewImpl* opener);
  ~WebViewImpl() override;

  HitTestResult HitTestResultForRootFramePos(const LayoutPoint&);

  void ConfigureAutoResizeMode();

  void SetIsAcceleratedCompositingActive(bool);
  void DoComposite();
  void ReallocateRenderer();
  void UpdateDeviceEmulationTransform();

  // Helper function: Widens the width of |source| by the specified margins
  // while keeping it smaller than page width.
  //
  // This method can only be called if the main frame is local.
  WebRect WidenRectWithinPageBounds(const WebRect& source,
                                    int target_margin,
                                    int minimum_margin);

  // PageWidgetEventHandler functions
  void HandleMouseLeave(LocalFrame&, const WebMouseEvent&) override;
  void HandleMouseDown(LocalFrame&, const WebMouseEvent&) override;
  void HandleMouseUp(LocalFrame&, const WebMouseEvent&) override;
  WebInputEventResult HandleMouseWheel(LocalFrame&,
                                       const WebMouseWheelEvent&) override;
  WebInputEventResult HandleGestureEvent(const WebGestureEvent&) override;
  WebInputEventResult HandleKeyEvent(const WebKeyboardEvent&) override;
  WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;

  WebInputEventResult HandleCapturedMouseEvent(const WebCoalescedInputEvent&);

  void EnablePopupMouseWheelEventListener(WebLocalFrameImpl* local_root);
  void DisablePopupMouseWheelEventListener();

  float DeviceScaleFactor() const;

  void SetRootGraphicsLayer(GraphicsLayer*);
  void SetRootLayer(scoped_refptr<cc::Layer>);

  LocalFrame* FocusedLocalFrameInWidget() const;
  LocalFrame* FocusedLocalFrameAvailableForIme() const;

  bool ScrollFocusedEditableElementIntoView();
  // Finds the zoom and scroll parameters for zooming into an editable element
  // with bounds |element_bounds_in_document| and caret bounds
  // |caret_bounds_in_document|. If the original element belongs to the local
  // root of MainFrameImpl(), then the bounds are exactly those of the element
  // and caret. Otherwise (when the editable element is inside an OOPIF), the
  // bounds are projection of the original element's bounds in the main frame
  // which is inside the layout area of some remote frame in this frame tree.
  void ComputeScaleAndScrollForEditableElementRects(
      const IntRect& element_bounds_in_document,
      const IntRect& caret_bounds_in_document,
      bool zoom_into_legible_scale,
      float& scale,
      IntPoint& scroll,
      bool& need_animation);

  // These member variables should not be accessed within calls to WebWidget
  // APIs. They can be called from within WebView APIs, and internal methods,
  // though these need to be sorted as being for the view or the widget also.
  struct ViewData {
    ViewData(WebViewClient* client) : client(client) {}

    // Can be null (e.g. unittests, shared workers, etc).
    WebViewClient* client;
    Persistent<Page> page;
  } as_view_;

  // These member variables should not be accessed within calls to WebView
  // APIs. They can be called from within WebWidget APIs, and internal methods,
  // though these need to be sorted as being for the view or the widget also.
  struct WidgetData {
    // Can be null (e.g. unittests, shared workers, etc).
    WebWidgetClient* client = nullptr;
  } as_widget_;

  Persistent<ChromeClient> chrome_client_;

  WebSize size_;
  // If true, automatically resize the layout view around its content.
  bool should_auto_resize_ = false;
  // The lower bound on the size when auto-resizing.
  IntSize min_auto_size_;
  // The upper bound on the size when auto-resizing.
  IntSize max_auto_size_;

  // An object that can be used to manipulate m_page->settings() without linking
  // against WebCore. This is lazily allocated the first time GetWebSettings()
  // is called.
  std::unique_ptr<WebSettingsImpl> web_settings_;

  // Keeps track of the current zoom level. 0 means no zoom, positive numbers
  // mean zoom in, negative numbers mean zoom out.
  double zoom_level_ = 0.;

  double minimum_zoom_level_;

  double maximum_zoom_level_;

  // Additional zoom factor used to scale the content by device scale factor.
  double zoom_factor_for_device_scale_factor_ = 0.;

  // This value, when multiplied by the font scale factor, gives the maximum
  // page scale that can result from automatic zooms.
  float maximum_legible_scale_ = 1.f;

  // The scale moved to by the latest double tap zoom, if any.
  float double_tap_zoom_page_scale_factor_ = 0.f;
  // Have we sent a double-tap zoom and not yet heard back the scale?
  bool double_tap_zoom_pending_ = false;

  // Used for testing purposes.
  bool enable_fake_page_scale_animation_for_testing_ = false;
  IntPoint fake_page_scale_animation_target_position_;
  float fake_page_scale_animation_page_scale_factor_ = 0.f;
  bool fake_page_scale_animation_use_anchor_ = false;

  float compositor_device_scale_factor_override_ = 0.f;
  TransformationMatrix device_emulation_transform_;

  // Webkit expects keyPress events to be suppressed if the associated keyDown
  // event was handled. Safari implements this behavior by peeking out the
  // associated WM_CHAR event if the keydown was handled. We emulate
  // this behavior by setting this flag if the keyDown was handled.
  bool suppress_next_keypress_event_ = false;

  // TODO(ekaramad): Can we remove this and make sure IME events are not called
  // when there is no page focus?
  // Represents whether or not this object should process incoming IME events.
  bool ime_accept_events_ = true;

  // The popup associated with an input/select element. The popup is owned via
  // closership (self-owned-but-deleted-via-close) by RenderWidget. We also hold
  // a reference here because we can extend the lifetime of the popup while
  // handling input events in order to compare its popup client after it was
  // closed.
  scoped_refptr<WebPagePopupImpl> page_popup_;

  // This stores the last hidden page popup. If a GestureTap attempts to open
  // the popup that is closed by its previous GestureTapDown, the popup remains
  // closed.
  scoped_refptr<WebPagePopupImpl> last_hidden_page_popup_;

  Persistent<DevToolsEmulator> dev_tools_emulator_;

  // Whether the user can press tab to focus links.
  bool tabs_to_links_ = false;

  // If set, the (plugin) element which has mouse capture.
  Persistent<HTMLPlugInElement> mouse_capture_element_;
  scoped_refptr<UserGestureToken> mouse_capture_gesture_token_;

  // WebViews, and WebWidgets, are used to host a Page and present it via a
  // WebLayerTreeView compositor. The WidgetClient() provides compositing
  // support for the WebView.
  // In some cases, a WidgetClient() is not provided, or it informs us that
  // it won't be presenting content via a compositor.
  // When not compositing, the |layer_tree_view_| will be null, otherwise it
  // would be non-null until closing.
  //
  // TODO(dcheng): All WebViewImpls should have an associated LayerTreeView,
  // but for various reasons, that's not the case... WebView plugin, printing,
  // workers, and tests don't use a compositor in their WebViews. Sometimes
  // they avoid the compositor by using a null client, and sometimes by having
  // the client return a null compositor. We should make things more consistent
  // and clear.
  const bool does_composite_;
  WebLayerTreeView* layer_tree_view_ = nullptr;
  cc::AnimationHost* animation_host_ = nullptr;

  scoped_refptr<cc::Layer> root_layer_;
  GraphicsLayer* root_graphics_layer_ = nullptr;
  GraphicsLayer* visual_viewport_container_layer_ = nullptr;
  bool matches_heuristics_for_gpu_rasterization_ = false;

  std::unique_ptr<FullscreenController> fullscreen_controller_;

  SkColor base_background_color_ = Color::kWhite;
  bool base_background_color_override_enabled_ = false;
  SkColor base_background_color_override_ = Color::kTransparent;
  bool background_color_override_enabled_ = false;
  SkColor background_color_override_ = Color::kTransparent;
  float zoom_factor_override_ = 0.f;

  bool should_dispatch_first_visually_non_empty_layout_ = false;
  bool should_dispatch_first_layout_after_finished_parsing_ = false;
  bool should_dispatch_first_layout_after_finished_loading_ = false;
  WebDisplayMode display_mode_ = kWebDisplayModeBrowser;

  FloatSize elastic_overscroll_;

  // When overriding the default page scale constraints, store the original so
  // we can revert to them when the override is removed.
  base::Optional<PageScaleConstraints> pre_override_default_constraints_;

  Persistent<EventListener> popup_mouse_wheel_event_listener_;

  // The local root whose document has |popup_mouse_wheel_event_listener_|
  // registered.
  WeakPersistent<WebLocalFrameImpl> local_root_with_empty_mouse_wheel_listener_;

  WebPageImportanceSignals page_importance_signals_;

  // We defer commits when transitioning to a new page. ChromeClientImpl calls
  // StopDeferringCommits() to release this when a new page is loaded.
  std::unique_ptr<cc::ScopedDeferMainFrameUpdate>
      scoped_defer_main_frame_update_;

  Persistent<ResizeViewportAnchor> resize_viewport_anchor_;

  // Set when a measurement begins, reset when the measurement is taken.
  base::Optional<base::TimeTicks> raf_aligned_input_start_time_;
  base::Optional<base::TimeTicks> update_layers_start_time_;
  base::Optional<base::TimeTicks> commit_compositor_frame_start_time_;
};

// We have no ways to check if the specified WebView is an instance of
// WebViewImpl because WebViewImpl is the only implementation of WebView.
DEFINE_TYPE_CASTS(WebViewImpl, WebView, webView, true, true);

}  // namespace blink

#endif