Chrome 源码阅读:跟踪一个鼠标事件的流程

打印 上一主题 下一主题

主题 560|帖子 560|积分 1680

我们通过在关键节点打断点的方式,去分析一个鼠标事件的流程。
我们知道chromium是多进程模子,那么,我们可以推测:一个鼠标消息先从主进程产生,再通过跨进程通讯发送给渲染进程,渲染进程再发送给WebFrame,最后被派发到目标Node上
于是,起首,我们在主进程,找到鼠标时间的最终消耗点,打上断点,进行分析:


主进程继续往下走,就是把事件通过跨进程通讯框架mojo发送过去的逻辑了:


接下来,我们要换个进程,在渲染进程打上断点,看看消息过来后,怎么走的流程:
起首搜索这个mojom的事件,确认渲染进程断点落脚处:

题外话:这个input_handler.mojom.cc到了渲染进程那就成了input_handler.mojom-blink.cc了。
这两个文件99%相似,只有少量的差别(定名空间、基础范例):

这两个类的基类是一样的:

这个类的头文件写明了,是由什么工具生成的:

很好奇生成源,我们也去看看:

  1. // Copyright 2020 The Chromium Authors
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. module blink.mojom;
  5. import "cc/mojom/browser_controls_state.mojom";
  6. import "cc/mojom/overscroll_behavior.mojom";
  7. import "cc/mojom/touch_action.mojom";
  8. import "mojo/public/mojom/base/string16.mojom";
  9. import "mojo/public/mojom/base/time.mojom";
  10. import "third_party/blink/public/mojom/input/gesture_event.mojom";
  11. import "third_party/blink/public/mojom/input/handwriting_gesture_result.mojom";
  12. import "third_party/blink/public/mojom/input/input_event_result.mojom";
  13. import "third_party/blink/public/mojom/input/input_event.mojom";
  14. import "third_party/blink/public/mojom/input/pointer_lock_context.mojom";
  15. import "third_party/blink/public/mojom/input/pointer_lock_result.mojom";
  16. import "third_party/blink/public/mojom/input/ime_host.mojom";
  17. import "third_party/blink/public/mojom/input/stylus_writing_gesture.mojom";
  18. import "third_party/blink/public/mojom/input/touch_event.mojom";
  19. import "third_party/blink/public/mojom/selection_menu/selection_menu_behavior.mojom";
  20. import "ui/base/ime/mojom/ime_types.mojom";
  21. import "ui/events/mojom/event_constants.mojom";
  22. import "ui/events/mojom/event_latency_metadata.mojom";
  23. import "ui/events/mojom/event.mojom";
  24. import "ui/events/mojom/scroll_granularity.mojom";
  25. import "ui/gfx/geometry/mojom/geometry.mojom";
  26. import "ui/gfx/range/mojom/range.mojom";
  27. import "ui/latency/mojom/latency_info.mojom";
  28. [EnableIf=is_android]
  29. import "third_party/blink/public/mojom/input/synchronous_compositor.mojom";
  30. // These structs are purposely duplicated from ui/events/mojom/event.mojom.
  31. // They map WebInputEvent <-> WebInputEvent across mojo.
  32. // We have to work at unifying them. The current problem is that the browser
  33. // uses WebInputEvents inside the render widget host and input router. Once
  34. // we move these to ui::Event's then we can get rid of these duplicated
  35. // mojom structs. Ideally the browser would use ui::Event up until we
  36. // pass the events into the renderer and just use a StructTraits to perform
  37. // conversion from ui::mojom::Event --> blink::WebInputEvent.
  38. struct KeyData {
  39.   int32 dom_key;
  40.   int32 dom_code;
  41.   int32 windows_key_code;
  42.   int32 native_key_code;
  43.   bool is_system_key;
  44.   bool is_browser_shortcut;
  45.   mojo_base.mojom.String16 text;
  46.   mojo_base.mojom.String16 unmodified_text;
  47. };
  48. struct PointerData {
  49.   int32 pointer_id;
  50.   float force;
  51.   double tilt_x;
  52.   double tilt_y;
  53.   float tangential_pressure;
  54.   int32 twist;
  55.   blink.mojom.Button button;
  56.   ui.mojom.EventPointerType pointer_type;
  57.   int32 movement_x;
  58.   int32 movement_y;
  59.   bool is_raw_movement_event;
  60.   gfx.mojom.PointF widget_position;
  61.   gfx.mojom.PointF screen_position;
  62.   MouseData? mouse_data;
  63.   int32 device_id;
  64. };
  65. struct WheelData {
  66.   float delta_x;
  67.   float delta_y;
  68.   float wheel_ticks_x;
  69.   float wheel_ticks_y;
  70.   float acceleration_ratio_x;
  71.   float acceleration_ratio_y;
  72.   uint8 phase;
  73.   uint8 momentum_phase;
  74.   blink.mojom.DispatchType cancelable;
  75.   uint8 event_action;
  76.   uint8 delta_units;
  77. };
  78. struct MouseData {
  79.   int32 click_count;
  80.   WheelData? wheel_data;
  81. };
  82. struct ScrollUpdate {
  83.   float velocity_x;
  84.   float velocity_y;
  85. };
  86. struct ScrollData {
  87.   float delta_x;
  88.   float delta_y;
  89.   ui.mojom.ScrollGranularity delta_units;
  90.   bool target_viewport;
  91.   blink.mojom.InertialPhaseState inertial_phase;
  92.   bool synthetic;
  93.   int32 pointer_count;
  94.   // Used for GestureScrollBegin type only. If this is true, we use the scroll
  95.   // sequence to do cursor control rather than scroll.
  96.   bool cursor_control;
  97.   ScrollUpdate? update_details;
  98. };
  99. struct PinchBeginData {
  100.   bool needs_wheel_event;
  101. };
  102. struct PinchUpdateData {
  103.   float scale;
  104.   bool zoom_disabled;
  105.   bool needs_wheel_event;
  106. };
  107. struct PinchEndData {
  108.   bool needs_wheel_event;
  109. };
  110. struct FlingData {
  111.   float velocity_x;
  112.   float velocity_y;
  113.   bool target_viewport;
  114.   bool prevent_boosting;
  115. };
  116. struct TapData {
  117.   int32 tap_count;
  118.   bool needs_wheel_event;
  119. };
  120. struct TapDownData {
  121.   int32 tap_down_count;
  122. };
  123. struct GestureData {
  124.   gfx.mojom.PointF screen_position;
  125.   gfx.mojom.PointF widget_position;
  126.   blink.mojom.GestureDevice source_device;
  127.   bool is_source_touch_event_set_blocking;
  128.   ui.mojom.EventPointerType primary_pointer_type;
  129.   int32 primary_unique_touch_event_id;
  130.   int32 unique_touch_event_id;
  131.   gfx.mojom.Size? contact_size;
  132.   ScrollData? scroll_data;
  133.   PinchBeginData? pinch_begin_data;
  134.   PinchUpdateData? pinch_update_data;
  135.   PinchEndData? pinch_end_data;
  136.   TapData? tap_data;
  137.   TapDownData? tap_down_data;
  138.   FlingData? fling_data;
  139. };
  140. struct TouchPoint {
  141.   blink.mojom.TouchState state;
  142.   float radius_x;
  143.   float radius_y;
  144.   float rotation_angle;
  145.   PointerData pointer_data;
  146. };
  147. struct TouchData {
  148.   blink.mojom.DispatchType cancelable;
  149.   bool moved_beyond_slop_region;
  150.   bool touch_start_or_first_move;
  151.   bool hovering;
  152.   uint32 unique_touch_event_id;
  153.   array<TouchPoint> touches;
  154. };
  155. struct Event {
  156.   blink.mojom.EventType type;
  157.   int32 modifiers;
  158.   mojo_base.mojom.TimeTicks timestamp;
  159.   ui.mojom.LatencyInfo latency;
  160.   ui.mojom.EventLatencyMetadata event_latency_metadata;
  161.   KeyData? key_data;
  162.   PointerData? pointer_data;
  163.   GestureData? gesture_data;
  164.   TouchData? touch_data;
  165. };
  166. // Represents the current state of overscroll.
  167. struct DidOverscrollParams {
  168.   gfx.mojom.Vector2dF accumulated_overscroll;
  169.   gfx.mojom.Vector2dF latest_overscroll_delta;
  170.   gfx.mojom.Vector2dF current_fling_velocity;
  171.   gfx.mojom.PointF causal_event_viewport_point;
  172.   cc.mojom.OverscrollBehavior overscroll_behavior;
  173. };
  174. // A struct wrapper for the TouchAction enumeration because
  175. // enumerations cannot be optional.
  176. struct TouchActionOptional {
  177.   cc.mojom.TouchAction touch_action;
  178. };
  179. // Types related to sending edit commands to the renderer.
  180. struct EditCommand {
  181.   string name;
  182.   string value;
  183. };
  184. // A structure that indicates selection offsets if the selection could be
  185. // established.
  186. struct SelectAroundCaretResult {
  187.   // The offset differences between the extended selection and the initial
  188.   // selection (which is a caret).
  189.   int32 extended_start_adjust;
  190.   int32 extended_end_adjust;
  191.   // The offset differences between the word selection (regardless of the
  192.   // extended selection granularity) and the initial selection (which is a
  193.   // caret).
  194.   int32 word_start_adjust;
  195.   int32 word_end_adjust;
  196. };
  197. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.input
  198. // GENERATED_JAVA_CLASS_NAME_OVERRIDE: SelectionGranularity
  199. enum SelectionGranularity {
  200.   kWord,
  201.   kSentence,
  202. };
  203. // An enumeration that describes the allowed non-directional pan action for the
  204. // element under pointer being considered.
  205. enum PanAction {
  206.   // No pan action allowed.
  207.   kNone,
  208.   // Pan action is scroll.
  209.   kScroll,
  210.   // Pan action moves cursor when initial touch move is in horizontal direction,
  211.   // or scrolls in the vertical direction.
  212.   kMoveCursorOrScroll,
  213.   // Pan action is stylus writable.
  214.   kStylusWritable,
  215. };
  216. // Interface exposed by the browser to the renderer.
  217. interface WidgetInputHandlerHost {
  218.   // When the renderer's main thread computes the touch action, send this to the
  219.   // browser.
  220.   SetTouchActionFromMain(cc.mojom.TouchAction touch_action);
  221.   // Sets the pan action possible for the element under pointer which could be
  222.   // one of the actions described under enum PanAction. Note that this is
  223.   // different from TouchAction and does not contain directional pan info.
  224.   SetPanAction(PanAction pan_action);
  225.   // Sent by the compositor when input scroll events are dropped due to bounds
  226.   // restrictions on the root scroll offset.
  227.   DidOverscroll(DidOverscrollParams params);
  228.   // Sent by the compositor when a GSB has started scrolling the viewport.
  229.   DidStartScrollingViewport();
  230.   // Required for cancelling an ongoing input method composition.
  231.   ImeCancelComposition();
  232.   // Sends the character bounds after every composition change
  233.   // to always have correct bound info.
  234.   ImeCompositionRangeChanged(gfx.mojom.Range range,
  235.                              array<gfx.mojom.Rect>? character_bounds,
  236.                              array<gfx.mojom.Rect>? line_bounds);
  237.   // Updates the mouse capture state of this widget. While capture is enabled,
  238.   // all mouse events, including those that don't hittest to this widget, will
  239.   // be targeted to this widget. This enables Blink to behave correctly when
  240.   // a scrollbar is being dragged, or text is being drag-highlighted, even
  241.   // when the mouse passes across different RenderWidget areas.
  242.   SetMouseCapture(bool capture);
  243.   // Updates the browser whether this main frame widget has ongoing autoscroll
  244.   // selection. Any further mouse up event should always be dispatched to the
  245.   // main frame in addition to it's event target (OOP child frame) if the state
  246.   // is active. This API should only ever be called on the InputHandler for a
  247.   // main frame's RenderWidgetHost.
  248.   SetAutoscrollSelectionActiveInMainFrame(bool autoscroll_selection);
  249.   // Requests locking the target of mouse events to a single element and
  250.   // removing the cursor from view.  Mostly used by the Pointer Lock API.
  251.   // See https://www.w3.org/TR/pointerlock/ for more info. This call is
  252.   // also used by Pepper Flash.
  253.   // |from_user_gesture| indicates whether this request came from a user
  254.   // gesture or not.
  255.   // |unadjusted_movement| indicates whether the request asked for raw mouse
  256.   // movement data or just what the operating system returns (often accelerated
  257.   // mouse movement).
  258.   // |result| kSuccess if the mouse has been locked or the appropriate error
  259.   // reason if not.
  260.   // |context| is one end of a mojo pipe that will stay connected as long as
  261.   // the mouse is locked. Is a NullRemote if |result| is not kSuccess.
  262.   RequestMouseLock(bool from_user_gesture,
  263.                    bool unadjusted_movement)
  264.       => (PointerLockResult result,
  265.           pending_remote<blink.mojom.PointerLockContext>? context);
  266. };
  267. // This interface provides the input actions associated with the FrameWidget.
  268. // Other input actions may also be dispatched via the WidgetInputHandler
  269. // interface. If frame input actions are dispatched the WidgetInputHandler
  270. // should be fetched via the associated interface request so that input calls
  271. // remain in order. See https://goo.gl/x4ee8A for more details.
  272. interface FrameWidgetInputHandler {
  273.   // Adds text decorations between a given valid start and end offsets in the
  274.   // currently focused editable field.
  275.   AddImeTextSpansToExistingText(
  276.     uint32 start, uint32 end, array<ui.mojom.ImeTextSpan> ime_text_spans);
  277.   // Clears text decorations type between a given valid start and end offsets
  278.   // in the currently focused editable field.
  279.   ClearImeTextSpansByType(
  280.     uint32 start, uint32 end, ui.mojom.ImeTextSpanType type);
  281.   // Sets the text composition to be between the given start and end offsets in
  282.   // the currently focused editable field.
  283.   SetCompositionFromExistingText(
  284.       int32 start, int32 end, array<ui.mojom.ImeTextSpan> ime_text_spans);
  285.   // Deletes the current selection plus the specified number of characters
  286.   // before and after the selection or caret.
  287.   ExtendSelectionAndDelete(int32 before, int32 after);
  288.   // Deletes the current selection plus the specified number of characters
  289.   // before and after the selection or caret.
  290.   ExtendSelectionAndReplace(uint32 before,
  291.                             uint32 after,
  292.                             mojo_base.mojom.String16 replacement_text);
  293.   // Deletes text before and after the current cursor position, excluding the
  294.   // selection. The lengths are supplied in Java chars (UTF-16 Code Unit),
  295.   // not in code points or in glyphs.
  296.   DeleteSurroundingText(int32 before, int32 after);
  297.   // Deletes text before and after the current cursor position, excluding the
  298.   // selection. The lengths are supplied in code points, not in Java chars
  299.   // (UTF-16 Code Unit) or in glyphs. Does nothing if there are one or more
  300.   // invalid surrogate pairs in the requested range
  301.   DeleteSurroundingTextInCodePoints(int32 before, int32 after);
  302.   // Selects between the given start and end offsets in the currently focused
  303.   // editable field.
  304.   SetEditableSelectionOffsets(int32 start, int32 end);
  305.   // Stylus Writing - perform Gesture action in input using gesture data.
  306.   HandleStylusWritingGestureAction(
  307.     blink.mojom.StylusWritingGestureData gesture_data)
  308.       => (HandwritingGestureResult result);
  309.   // Message payload is the name/value of a WebCore edit command to execute.
  310.   ExecuteEditCommand(string command, mojo_base.mojom.String16? value);
  311.   // These messages are typically generated from context menus and request the
  312.   // renderer to apply the specified operation to the current selection.
  313.   Undo();
  314.   Redo();
  315.   Cut();
  316.   Copy();
  317.   CopyToFindPboard();
  318.   CenterSelection();
  319.   Paste();
  320.   PasteAndMatchStyle();
  321.   Delete();
  322.   SelectAll();
  323.   CollapseSelection();
  324.   // Pushed from the browser to the renderer each time the IME is activated,
  325.   // e.g. an editable element becomes focused.
  326.   [EnableIf=is_android]
  327.   PassImeRenderWidgetHost(pending_remote<ImeRenderWidgetHost> remote);
  328.   // Replaces the selected region or a word around the cursor with the
  329.   // specified string.
  330.   Replace(mojo_base.mojom.String16 word);
  331.   // Replaces the misspelling in the selected region with the specified string.
  332.   ReplaceMisspelling(mojo_base.mojom.String16 word);
  333.   // Requests the renderer to select the region between two points.
  334.   // Expects a SelectRange_ACK message when finished.
  335.   SelectRange(gfx.mojom.Point base, gfx.mojom.Point extent);
  336.   // Sent by the browser to ask the renderer to adjust the selection start and
  337.   // end points by the given amounts. A negative amount moves the selection
  338.   // towards the beginning of the document, a positive amount moves the
  339.   // selection towards the end of the document. Will send show selection menu
  340.   // event when needed.
  341.   AdjustSelectionByCharacterOffset(
  342.       int32 start, int32 end, SelectionMenuBehavior behavior);
  343.   // Requests the renderer to select the specified granularity around caret and
  344.   // to potentially show the selection handles and / or context menu after
  345.   // selection.
  346.   // Expects ack with new selection information when finished, or null if the
  347.   // selection failed.
  348.   SelectAroundCaret(SelectionGranularity granularity, bool should_show_handle,
  349.                     bool should_show_context_menu)
  350.       => (SelectAroundCaretResult? result);
  351.   // Requests the renderer to move the selection extent point to a new position.
  352.   // Expects a MoveRangeSelectionExtent_ACK message when finished.
  353.   MoveRangeSelectionExtent(gfx.mojom.Point extent);
  354.   // Tells the renderer to scroll the currently focused node into view only if
  355.   // the currently focused node is a Text node (textfield, text area or content
  356.   // editable divs).
  357.   ScrollFocusedEditableNodeIntoView();
  358.   // Replies when the next PageScaleAnimation has completed. Can only be called
  359.   // on the outermost main frame. Can be used to reliably wait for a
  360.   // ScrollFocusedEditableNodeIntoView to complete since that may create a
  361.   // PageScaleAnimation which can take several frames to complete.
  362.   // ScrollFocusedEditableNodeIntoView cannot use a reply callback for this
  363.   // since it may be called on a subframe but the scroll will be completed in
  364.   // another renderer when it bubbles up to the root. Additionally, the caller
  365.   // may not be the one to have called ScrollFocusedEditableNodeIntoView; for
  366.   // example, a test that simulates tapping an input box.
  367.   WaitForPageScaleAnimationForTesting() => ();
  368.   // Requests the renderer to move the caret selection toward the point.
  369.   MoveCaret(gfx.mojom.Point point);
  370. };
  371. // An enumeration describing the active and focus states. If a widget is
  372. // focused then it must also be active, therefore there is no focused and
  373. // not active value in this enumeration. All widgets in a tab will have
  374. // the same active state. Active state is tab specific, and focus state is
  375. // frame specific. See
  376. // https://www.chromium.org/developers/design-documents/aura/focus-and-activation/
  377. enum FocusState
  378. {
  379.   kFocused,
  380.   kNotFocusedAndActive,
  381.   kNotFocusedAndNotActive
  382. };
  383. // Interface exposed by the renderer to the browser. This class represents
  384. // an input interface for an associated Widget object. See FrameWidgetInputHandler
  385. // for an interface at the frame level.
  386. interface WidgetInputHandler {
  387.   // Tells widget focus has been changed.
  388.   SetFocus(FocusState state);
  389.   // Tells widget mouse capture has been lost.
  390.   MouseCaptureLost();
  391.   // This message notifies the renderer that the next key event is bound to one
  392.   // or more pre-defined edit commands. If the next key event is not handled
  393.   // by blink, the specified edit commands shall be executed against current
  394.   // focused frame.
  395.   // Parameters
  396.   // * edit_commands
  397.   //   See t_p/b/renderer/core/editing/commands/editing_command_type.h
  398.   //   Contains one or more edit commands.
  399.   // See t_p/b/renderer/core/editing/commands/editor_command.cc for
  400.   // detailed definition of webkit edit commands.
  401.   //
  402.   // This message must be sent just before sending a key event.
  403.   SetEditCommandsForNextKeyEvent(array<EditCommand> commands);
  404.   // Sends the cursor visibility state to the render widget.
  405.   CursorVisibilityChanged(bool visible);
  406.   // This message sends a string being composed with an input method.
  407.   // Note, the response is specifically for Devtools to learn about completion
  408.   ImeSetComposition(mojo_base.mojom.String16 text,
  409.                     array<ui.mojom.ImeTextSpan> ime_text_spans,
  410.                     gfx.mojom.Range range, int32 start, int32 end) => ();
  411.   // This message deletes the current composition, inserts specified text, and
  412.   // moves the cursor.
  413.    // Note, the response is specifically for Devtools to learn about completion
  414.   ImeCommitText(mojo_base.mojom.String16 text,
  415.                 array<ui.mojom.ImeTextSpan> ime_text_spans,
  416.                 gfx.mojom.Range range, int32 relative_cursor_position) => ();
  417.   // This message inserts the ongoing composition.
  418.   ImeFinishComposingText(bool keep_selection);
  419.   // Request from browser to update text input state.
  420.   RequestTextInputStateUpdate();
  421.   // Request from browser to update the cursor and composition information which
  422.   // will be sent through ImeCompositionRangeChanged. Setting
  423.   // |immediate_request| to true  will lead to an immediate update. If
  424.   // |monitor_updates| is set to true then changes to text selection or regular
  425.   // updates in each compositor frame (when there is a change in composition
  426.   // info) will lead to updates being sent to the browser.
  427.   RequestCompositionUpdates(bool immediate_request, bool monitor_request);
  428.   // Sends an input event to the render widget. The browser should use this
  429.   // API if it wants to know about the result of the rendering handling
  430.   // the event. The callback may be delayed based on the event running on
  431.   // the main thread so DispatchNonBlockingEvent is always preferred if
  432.   // you don't require notification.
  433.   DispatchEvent(Event event)
  434.       => (blink.mojom.InputEventResultSource source,
  435.          ui.mojom.LatencyInfo updated_latency,
  436.          blink.mojom.InputEventResultState state,
  437.          DidOverscrollParams? overscroll,
  438.          TouchActionOptional? touch_action);
  439.   // Sends a non-blocking input event to the render widget. The behaviour
  440.   // of this API is the same as DispatchEvent just that there is no callback
  441.   // after the event is processed.
  442.   DispatchNonBlockingEvent(Event event);
  443.   // Forces input to be flushed and resolves the callback only once the input
  444.   // has been fully processed, meaning its effects are visible to the full
  445.   // system. In practice, this will force a redraw and wait until the new
  446.   // CompositorFrame (containing all changes caused by prior input) has been
  447.   // displayed.
  448.   WaitForInputProcessed() => ();
  449.   // Attach the synchronous compositor interface. This method only
  450.   // should be called for Android WebView.
  451.   [EnableIf=is_android]
  452.   AttachSynchronousCompositor(
  453.       pending_remote<SynchronousCompositorControlHost> control_host,
  454.       pending_associated_remote<SynchronousCompositorHost> host,
  455.       pending_associated_receiver<SynchronousCompositor> compositor_request);
  456.   // Return an associated FrameWidgetInputHandler interface so that input
  457.   // messages to the frame associated with this widget can be sent
  458.   // serially.
  459.   GetFrameWidgetInputHandler(
  460.       pending_associated_receiver<FrameWidgetInputHandler> interface_request);
  461.   // Notifies the renderer whether hiding/showing the browser controls is
  462.   // enabled, what the current state should be, and whether or not to
  463.   // animate to the proper state.
  464.   UpdateBrowserControlsState(cc.mojom.BrowserControlsState constraints,
  465.                              cc.mojom.BrowserControlsState current,
  466.                              bool animate);
  467. };
复制代码
可见,这个生成的不止一个事件,包含了大部门用户事件了。去看看所在目录,也开端认识blink的目录结构了:

后面我们再详细介绍这套mojo跨进程通讯框架的细节。

言归正传,我们attach到render进程,继续打断点跟踪鼠标事件。
想在渲染进程找到WidgetInputHandler类对应的消息,只需要在后面加个Impl即可,我们通过符号跳转,找到WidgetInputHandlerImpl类:


接下来,中心弯弯绕绕太多,我们直接在node打个断点,看看鼠标事件如何通报到node具体的处理逻辑中的:

事件起首被捕获并封装为一个MouseEvent或PointerEvent对象。然后通过EventDispatcher类和相关方法,事件被分发到目标Node。对应的HTML元素(通过HTMLElement和特化的TextControlInnerEditorElement)会处理这个事件,然后这个时间触发默认基类的处理器。
WebFrameWidget:继续自WebWidget,但是大部门函数依然是虚函数,用于专门负责处理一个WebFrame(即一个网页框架)的渲染和事件。假如要想表现一个网页,那么需要继续自WebFrameWidget并实现相关纯虚函数。
WebFrameWidgetImpl:是WebFrameWidget在blink里的一个具体实现类。它实现了接口中定义的全部方法,并提供了框架的具体行为。WebFrameWidgetImpl负责实际的绘图逻辑、输入事件处理、视图的更新和巨细调整等。这个实现将抽象的行为具体化,它通过调用Blink渲染引擎的其他组件,如布局引擎、绘图系统等,来完成对Web内容的渲染和事件处理。WebFrameWidgetImpl是Web内容在Blink中被渲染的核心地方,它直接与底层的渲染流水线交互。
讲到这里,也要引出一个重量级的基类:Node:
   Node 类是一个非常重要的基类,它表示文档中的一个节点。Node 类扮演了核心角色,以下是对 Node 类及其作用的更详细介绍:
  

  • 层次结构:
    Node 类位于 DOM(文档对象模子)层次结构中的基础位置。在 DOM 中,全部的元素、文本内容和属性都被视为节点。因此,Node 类提供了一系列的基础方法和属性,用于管理节点之间的关系(例如父子关系和兄弟关系)、节点的遍历以及节点的基本操纵(比如插入、更换、删除)。
  • 事件模子:
    Node 类照旧事件模子的一部门。在 Blink 中,事件通常会在节点之间传播,遵循捕获阶段、目标阶段和冒泡阶段。Node 类提供了事件处理的相关方法,比如绑定事件监听器、分发事件等。当事件发生时,比如用户的点击或键盘操纵,它会被分发到精确的 Node 对象,并且通过事件监听器进行相应的处理。
  • 渲染:
    虽然 Node 类自己并不直接处理渲染,但它的派生类,如 Element 和特化后的 HTMLElement,会存储与渲染相关的属性(例如样式信息)。这些类将 Node 的基础功能扩展到了渲染管线中,这样渲染引擎就可以利用这些信息来出现视觉元素。
  • 范例多样性:
    DOM 中有差别范例的节点,包括但不限于元素节点(Element)、文本节点(Text)、注释节点(Comment)和文档节点(Document)。Node 类是这些具体节点范例的基类,通过继续和多态,差别范例的节点可以拥有特化的行为,并且仍旧可以大概通过 Node 类的接口进行通用处理。
  • API 和脚本接口:
    Node 类还提供了一系列的 API,供 JavaScript 脚本访问和操纵节点。开辟者可以通过这些 API 查询节点信息、修改节点结构、动态添加或移除节点等。这为开辟者提供了强盛的能力来改变页面内容和行为。
  总的来说,Node 类是 Blink 和 Web 开辟者用来操纵和理解 Web 页面结构的基础,它为构建、遍历和交互提供了基本的框架。通过 Node 及其派生类,Blink 渲染引擎可以大概将结构化的 HTML 文档转化为用户可以看到和交互的网页。
  未完待续 ....

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

反转基因福娃

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表